]> saetta.ns0.it Git - libgfeed/commitdiff
Initial import.
authorAndrea Zagli <azagli@libero.it>
Sat, 6 Jan 2007 14:42:33 +0000 (14:42 +0000)
committerAndrea Zagli <azagli@libero.it>
Sat, 6 Jan 2007 14:42:33 +0000 (14:42 +0000)
git-svn-id: http://saetta.homelinux.org/svn/libgfeed/trunk@1 766e3509-7fc5-439a-ae96-336fe19d476f

94 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
config.h.in [new file with mode: 0644]
configure.ac [new file with mode: 0644]
docs/Makefile.am [new file with mode: 0644]
docs/reference/Makefile.am [new file with mode: 0644]
docs/reference/libgfeed-docs.sgml [new file with mode: 0644]
docs/reference/libgfeed-overrides.txt [new file with mode: 0644]
docs/reference/libgfeed-sections.txt [new file with mode: 0644]
docs/reference/libgfeed-undocumented.txt [new file with mode: 0644]
docs/reference/libgfeed.types [new file with mode: 0644]
docs/reference/tmpl/atom.sgml [new file with mode: 0644]
docs/reference/tmpl/atomcategory.sgml [new file with mode: 0644]
docs/reference/tmpl/atomcommon.sgml [new file with mode: 0644]
docs/reference/tmpl/atomcontent.sgml [new file with mode: 0644]
docs/reference/tmpl/atomdate.sgml [new file with mode: 0644]
docs/reference/tmpl/atomentry.sgml [new file with mode: 0644]
docs/reference/tmpl/atomgenerator.sgml [new file with mode: 0644]
docs/reference/tmpl/atomid.sgml [new file with mode: 0644]
docs/reference/tmpl/atomlink.sgml [new file with mode: 0644]
docs/reference/tmpl/atomperson.sgml [new file with mode: 0644]
docs/reference/tmpl/atomsource.sgml [new file with mode: 0644]
docs/reference/tmpl/atomtext.sgml [new file with mode: 0644]
docs/reference/tmpl/gfeed.sgml [new file with mode: 0644]
docs/reference/tmpl/libgfeed-unused.sgml [new file with mode: 0644]
docs/reference/tmpl/rss.sgml [new file with mode: 0644]
docs/reference/tmpl/rsscategory.sgml [new file with mode: 0644]
docs/reference/tmpl/rsschannel.sgml [new file with mode: 0644]
docs/reference/tmpl/rsschannelitem.sgml [new file with mode: 0644]
docs/reference/tmpl/rsscloud.sgml [new file with mode: 0644]
docs/reference/tmpl/rssenclosure.sgml [new file with mode: 0644]
docs/reference/tmpl/rssguid.sgml [new file with mode: 0644]
docs/reference/tmpl/rssimage.sgml [new file with mode: 0644]
docs/reference/tmpl/rsssource.sgml [new file with mode: 0644]
docs/reference/tmpl/rsstextinput.sgml [new file with mode: 0644]
docs/reference/version.xml.in [new file with mode: 0644]
libgfeed.pc.in [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/atom.c [new file with mode: 0644]
src/atom.h [new file with mode: 0644]
src/atomcategory.c [new file with mode: 0644]
src/atomcategory.h [new file with mode: 0644]
src/atomcommon.c [new file with mode: 0644]
src/atomcommon.h [new file with mode: 0644]
src/atomcontent.c [new file with mode: 0644]
src/atomcontent.h [new file with mode: 0644]
src/atomdate.c [new file with mode: 0644]
src/atomdate.h [new file with mode: 0644]
src/atomentry.c [new file with mode: 0644]
src/atomentry.h [new file with mode: 0644]
src/atomgenerator.c [new file with mode: 0644]
src/atomgenerator.h [new file with mode: 0644]
src/atomid.c [new file with mode: 0644]
src/atomid.h [new file with mode: 0644]
src/atomlink.c [new file with mode: 0644]
src/atomlink.h [new file with mode: 0644]
src/atomperson.c [new file with mode: 0644]
src/atomperson.h [new file with mode: 0644]
src/atomsource.c [new file with mode: 0644]
src/atomsource.h [new file with mode: 0644]
src/atomtext.c [new file with mode: 0644]
src/atomtext.h [new file with mode: 0644]
src/gfeed.h [new file with mode: 0644]
src/rss.c [new file with mode: 0644]
src/rss.h [new file with mode: 0644]
src/rsscategory.c [new file with mode: 0644]
src/rsscategory.h [new file with mode: 0644]
src/rsschannel.c [new file with mode: 0644]
src/rsschannel.h [new file with mode: 0644]
src/rsschannelitem.c [new file with mode: 0644]
src/rsschannelitem.h [new file with mode: 0644]
src/rsscloud.c [new file with mode: 0644]
src/rsscloud.h [new file with mode: 0644]
src/rssenclosure.c [new file with mode: 0644]
src/rssenclosure.h [new file with mode: 0644]
src/rssguid.c [new file with mode: 0644]
src/rssguid.h [new file with mode: 0644]
src/rssimage.c [new file with mode: 0644]
src/rssimage.h [new file with mode: 0644]
src/rsssource.c [new file with mode: 0644]
src/rsssource.h [new file with mode: 0644]
src/rsstextinput.c [new file with mode: 0644]
src/rsstextinput.h [new file with mode: 0644]
test/Makefile.am [new file with mode: 0644]
test/test_atom.c [new file with mode: 0644]
test/test_atom_load.c [new file with mode: 0644]
test/test_atom_load_buffer.c [new file with mode: 0644]
test/test_rss.c [new file with mode: 0644]
test/test_rss_load.c [new file with mode: 0644]
test/test_rss_load_buffer.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..948556f
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Andrea Zagli <azagli@inwind.it>
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..5ab7695
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,504 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..b93368d
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,28 @@
+2006-09-05 Andrea Zagli <azagli@inwind.it>
+
+       * rss.c:
+       * rss.h: added rss_new_from_buffer()
+       * test/Makefile.am:
+       * test/test_rss_load_buffer: new test
+
+2006-09-03 Andrea Zagli <azagli@inwind.it>
+
+       * src/Makefile.am: changed $(includedir)
+       * libgfeed.pc.in: changed Cflags
+       * atom.c:
+       * atom.h: added atom_new_from_buffer()
+       * test/Makefile.am:
+       * test/test_atom_load_buffer: new test
+
+2006-08-23 Andrea Zagli <azagli@inwind.it>
+
+       * changed license headers on source code from GPL to LGPL
+       * COPYING now is the LGLP's text
+
+2006-06-10 Andrea Zagli <azagli@inwind.it>
+
+       * added more api documentation
+
+2006-05-18 Andrea Zagli <azagli@inwind.it>
+
+       * added support for Atom file v1.0 based on http://www.ietf.org/rfc/rfc4287.txt
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..4c0b500
--- /dev/null
@@ -0,0 +1,7 @@
+SUBDIRS = src test docs
+
+EXTRA_DIST = libgfeed.pc.in
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libgfeed.pc
+
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..8622f26
--- /dev/null
@@ -0,0 +1,71 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..7d51124
--- /dev/null
@@ -0,0 +1,52 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+AC_INIT([libgfeed], [0.1.1], [azagli@inwind.it])
+AC_CONFIG_SRCDIR([src/rss.c])
+AC_CONFIG_HEADER([config.h])
+
+AM_INIT_AUTOMAKE
+AM_MAINTAINER_MODE
+AC_LIBTOOL_WIN32_DLL
+
+AC_CANONICAL_SYSTEM
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+GTK_DOC_CHECK
+
+# Checks for libraries.
+PKG_CHECK_MODULES([GFEED], [glib-2.0 >= 2.6.0
+                            gobject-2.0 >= 2.6.0
+                            libxml-2.0 >= 2.6.0])
+
+AC_SUBST(GFEED_CFLAGS)
+AC_SUBST(GFEED_LIBS)
+
+# Checks for header files.
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_STRUCT_TM
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_FUNC_STRFTIME
+
+AC_CONFIG_FILES([
+  libgfeed.pc
+  Makefile
+  src/Makefile
+  test/Makefile
+  docs/Makefile
+  docs/reference/Makefile
+  docs/reference/version.xml
+])
+AC_OUTPUT
diff --git a/docs/Makefile.am b/docs/Makefile.am
new file mode 100644 (file)
index 0000000..f3ddc22
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = reference
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
new file mode 100644 (file)
index 0000000..09f8c12
--- /dev/null
@@ -0,0 +1,78 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.6 at least.
+AUTOMAKE_OPTIONS = 1.6
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE = libgfeed
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR = ../../src
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" 
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB = $(top_srcdir)/src/*.h
+CFILE_GLOB = $(top_srcdir)/src/*.c
+
+# Header files to ignore when scanning.
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES=
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files = version.xml
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+INCLUDES = -I$(top_srcdir)/src $(GFEED_CFLAGS)
+GTKDOC_LIBS = $(top_builddir)/src/libgfeed.la $(GFEED_LIBS)
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST += version.xml.in
diff --git a/docs/reference/libgfeed-docs.sgml b/docs/reference/libgfeed-docs.sgml
new file mode 100644 (file)
index 0000000..e61d1da
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
+               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+  <bookinfo>
+    <title>LibGFeed Reference Manual</title>
+    <releaseinfo>for LibGFeed &version;</releaseinfo>
+  </bookinfo>
+
+  <chapter>
+    <title>RSS API reference</title>
+    <xi:include href="xml/rss.xml"/>
+    <xi:include href="xml/rsschannel.xml"/>
+    <xi:include href="xml/rsschannelitem.xml"/>
+    <xi:include href="xml/rssimage.xml"/>
+    <xi:include href="xml/rssguid.xml"/>
+    <xi:include href="xml/rsstextinput.xml"/>
+    <xi:include href="xml/rsscloud.xml"/>
+    <xi:include href="xml/rsscategory.xml"/>
+    <xi:include href="xml/rsssource.xml"/>
+    <xi:include href="xml/rssenclosure.xml"/>
+  </chapter>
+
+  <chapter>
+    <title>ATOM API reference</title>
+    <xi:include href="xml/atom.xml"/>
+    <xi:include href="xml/atomcategory.xml"/>
+    <xi:include href="xml/atomcommon.xml"/>
+    <xi:include href="xml/atomcontent.xml"/>
+    <xi:include href="xml/atomdate.xml"/>
+    <xi:include href="xml/atomentry.xml"/>
+    <xi:include href="xml/atomgenerator.xml"/>
+    <xi:include href="xml/atomid.xml"/>
+    <xi:include href="xml/atomlink.xml"/>
+    <xi:include href="xml/atomperson.xml"/>
+    <xi:include href="xml/atomsource.xml"/>
+    <xi:include href="xml/atomtext.xml"/>
+  </chapter>
+</book>
diff --git a/docs/reference/libgfeed-overrides.txt b/docs/reference/libgfeed-overrides.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs/reference/libgfeed-sections.txt b/docs/reference/libgfeed-sections.txt
new file mode 100644 (file)
index 0000000..111ce6d
--- /dev/null
@@ -0,0 +1,241 @@
+<SECTION>
+<FILE>rss</FILE>
+<TITLE>Rss</TITLE>
+Rss
+rss_new
+rss_new_from_file
+rss_new_from_buffer
+rss_get_xml_doc
+rss_save_file
+</SECTION>
+
+<SECTION>
+<FILE>rsschannel</FILE>
+RSSCHANNEL_DAY_MONDAY
+RSSCHANNEL_DAY_TUESDAY
+RSSCHANNEL_DAY_WEDNESDAY
+RSSCHANNEL_DAY_THURSDAY
+RSSCHANNEL_DAY_FRIDAY
+RSSCHANNEL_DAY_SATURDAY
+RSSCHANNEL_DAY_SUNDAY
+RSSCHANNEL_HOUR_0
+RSSCHANNEL_HOUR_1
+RSSCHANNEL_HOUR_2
+RSSCHANNEL_HOUR_3
+RSSCHANNEL_HOUR_4
+RSSCHANNEL_HOUR_5
+RSSCHANNEL_HOUR_6
+RSSCHANNEL_HOUR_7
+RSSCHANNEL_HOUR_8
+RSSCHANNEL_HOUR_9
+RSSCHANNEL_HOUR_10
+RSSCHANNEL_HOUR_11
+RSSCHANNEL_HOUR_12
+RSSCHANNEL_HOUR_13
+RSSCHANNEL_HOUR_14
+RSSCHANNEL_HOUR_15
+RSSCHANNEL_HOUR_16
+RSSCHANNEL_HOUR_17
+RSSCHANNEL_HOUR_18
+RSSCHANNEL_HOUR_19
+RSSCHANNEL_HOUR_20
+RSSCHANNEL_HOUR_21
+RSSCHANNEL_HOUR_22
+RSSCHANNEL_HOUR_23
+<TITLE>RssChannel</TITLE>
+RssChannel
+rss_channel_new
+rss_channel_new_from_xml
+rss_channel_add_category
+rss_channel_get_categories
+rss_channel_add_item
+rss_channel_remove_item
+rss_channel_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>rsschannelitem</FILE>
+<TITLE>RssChannelItem</TITLE>
+RssChannelItem
+rss_channel_item_new
+rss_channel_item_new_from_xml
+rss_channel_item_add_category
+rss_channel_item_get_categories
+rss_channel_item_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>rssimage</FILE>
+<TITLE>RssImage</TITLE>
+RssImage
+rss_image_new
+rss_image_new_from_xml
+rss_image_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>rssguid</FILE>
+<TITLE>RssGuid</TITLE>
+RssGuid
+rss_guid_new
+rss_guid_new_from_xml
+rss_guid_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atom</FILE>
+<TITLE>Atom</TITLE>
+Atom
+atom_new
+atom_new_from_file
+atom_new_from_buffer
+atom_get_xml_doc
+atom_save_file
+</SECTION>
+
+<SECTION>
+<FILE>rsstextinput</FILE>
+<TITLE>RssTextInput</TITLE>
+RssTextInput
+rss_text_input_new
+rss_text_input_new_from_xml
+rss_text_input_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>rsscloud</FILE>
+<TITLE>RssCloud</TITLE>
+RssCloud
+rss_cloud_new
+rss_cloud_new_from_xml
+rss_cloud_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>rsscategory</FILE>
+<TITLE>RssCategory</TITLE>
+RssCategory
+rss_category_new
+rss_category_new_from_xml
+rss_category_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>rsssource</FILE>
+<TITLE>RssSource</TITLE>
+RssSource
+rss_source_new
+rss_source_new_from_xml
+rss_source_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>rssenclosure</FILE>
+<TITLE>RssEnclosure</TITLE>
+RssEnclosure
+rss_enclosure_new
+rss_enclosure_new_from_xml
+rss_enclosure_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atomcommon</FILE>
+<TITLE>AtomCommon</TITLE>
+AtomCommon
+atom_common_new
+atom_common_set_properties_from_xml
+atom_common_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atomdate</FILE>
+<TITLE>AtomDate</TITLE>
+AtomDate
+atom_date_new
+atom_date_new_from_xml
+atom_date_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atomid</FILE>
+<TITLE>AtomID</TITLE>
+AtomID
+atom_id_new
+atom_id_new_from_xml
+atom_id_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atomcontent</FILE>
+<TITLE>AtomContent</TITLE>
+AtomContent
+AtomContentType
+atom_content_new
+atom_content_new_from_xml
+atom_content_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atomperson</FILE>
+<TITLE>AtomPerson</TITLE>
+AtomPerson
+atom_person_new
+atom_person_new_from_xml
+atom_person_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atomtext</FILE>
+<TITLE>AtomText</TITLE>
+AtomText
+AtomTextType
+atom_text_new
+atom_text_new_from_xml
+atom_text_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atomcategory</FILE>
+<TITLE>AtomCategory</TITLE>
+AtomCategory
+atom_category_new
+atom_category_new_from_xml
+atom_category_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atomgenerator</FILE>
+<TITLE>AtomGenerator</TITLE>
+AtomGenerator
+atom_generator_new
+atom_generator_new_from_xml
+atom_generator_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atomlink</FILE>
+<TITLE>AtomLink</TITLE>
+AtomLink
+atom_link_new
+atom_link_new_from_xml
+atom_link_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atomentry</FILE>
+<TITLE>AtomEntry</TITLE>
+AtomEntry
+atom_entry_new
+atom_entry_new_from_xml
+atom_entry_get_xml
+</SECTION>
+
+<SECTION>
+<FILE>atomsource</FILE>
+<TITLE>AtomSource</TITLE>
+AtomSource
+atom_source_new
+atom_source_new_from_xml
+atom_source_get_xml
+</SECTION>
+
diff --git a/docs/reference/libgfeed-undocumented.txt b/docs/reference/libgfeed-undocumented.txt
new file mode 100644 (file)
index 0000000..69b2fdf
--- /dev/null
@@ -0,0 +1,168 @@
+44% symbol docs coverage.
+128 symbols documented.
+0 symbols incomplete.
+160 not documented.
+
+
+Atom
+AtomCategory
+AtomCommon
+AtomContent
+AtomContentType
+AtomDate
+AtomEntry
+AtomGenerator
+AtomID
+AtomLink
+AtomPerson
+AtomSource
+AtomText
+AtomTextType
+RSSCHANNEL_DAY_FRIDAY
+RSSCHANNEL_DAY_MONDAY
+RSSCHANNEL_DAY_SATURDAY
+RSSCHANNEL_DAY_SUNDAY
+RSSCHANNEL_DAY_THURSDAY
+RSSCHANNEL_DAY_TUESDAY
+RSSCHANNEL_DAY_WEDNESDAY
+RSSCHANNEL_HOUR_0
+RSSCHANNEL_HOUR_1
+RSSCHANNEL_HOUR_10
+RSSCHANNEL_HOUR_11
+RSSCHANNEL_HOUR_12
+RSSCHANNEL_HOUR_13
+RSSCHANNEL_HOUR_14
+RSSCHANNEL_HOUR_15
+RSSCHANNEL_HOUR_16
+RSSCHANNEL_HOUR_17
+RSSCHANNEL_HOUR_18
+RSSCHANNEL_HOUR_19
+RSSCHANNEL_HOUR_2
+RSSCHANNEL_HOUR_20
+RSSCHANNEL_HOUR_21
+RSSCHANNEL_HOUR_22
+RSSCHANNEL_HOUR_23
+RSSCHANNEL_HOUR_3
+RSSCHANNEL_HOUR_4
+RSSCHANNEL_HOUR_5
+RSSCHANNEL_HOUR_6
+RSSCHANNEL_HOUR_7
+RSSCHANNEL_HOUR_8
+RSSCHANNEL_HOUR_9
+Rss
+RssCategory
+RssChannel
+RssChannelItem
+RssCloud
+RssEnclosure
+RssGuid
+RssImage
+RssSource
+RssTextInput
+atom_category_get_xml
+atom_category_new
+atom_category_new_from_xml
+atom_common_get_xml
+atom_common_new
+atom_common_set_properties_from_xml
+atom_content_get_xml
+atom_content_new
+atom_content_new_from_xml
+atom_date_get_xml
+atom_date_new
+atom_date_new_from_xml
+atom_entry_get_xml
+atom_entry_new
+atom_entry_new_from_xml
+atom_generator_get_xml
+atom_generator_new
+atom_generator_new_from_xml
+atom_get_xml_doc
+atom_id_get_xml
+atom_id_new
+atom_id_new_from_xml
+atom_link_get_xml
+atom_link_new
+atom_link_new_from_xml
+atom_new
+atom_new_from_buffer
+atom_new_from_file
+atom_person_get_xml
+atom_person_new
+atom_person_new_from_xml
+atom_save_file
+atom_source_get_xml
+atom_source_new
+atom_source_new_from_xml
+atom_text_get_xml
+atom_text_new
+atom_text_new_from_xml
+rss_category_get_xml
+rss_category_new
+rss_category_new_from_xml
+rss_channel_add_category
+rss_channel_add_item
+rss_channel_get_categories
+rss_channel_get_xml
+rss_channel_item_add_category
+rss_channel_item_get_categories
+rss_channel_item_get_xml
+rss_channel_item_new
+rss_channel_item_new_from_xml
+rss_channel_new
+rss_channel_new_from_xml
+rss_channel_remove_item
+rss_cloud_get_xml
+rss_cloud_new
+rss_cloud_new_from_xml
+rss_enclosure_get_xml
+rss_enclosure_new
+rss_enclosure_new_from_xml
+rss_get_xml_doc
+rss_guid_get_xml
+rss_guid_new
+rss_guid_new_from_xml
+rss_image_get_xml
+rss_image_new
+rss_image_new_from_xml
+rss_new
+rss_new_from_buffer
+rss_new_from_file
+rss_save_file
+rss_source_get_xml
+rss_source_new
+rss_source_new_from_xml
+rss_text_input_get_xml
+rss_text_input_new
+rss_text_input_new_from_xml
+
+
+atom:Long_Description
+atom:Short_Description
+atomcategory:Long_Description
+atomcommon:Long_Description
+atomcommon:Short_Description
+atomcontent:Long_Description
+atomdate:Long_Description
+atomdate:Short_Description
+atomentry:Long_Description
+atomgenerator:Long_Description
+atomid:Long_Description
+atomlink:Long_Description
+atomperson:Long_Description
+atomsource:Short_Description
+atomtext:Long_Description
+atomtext:Short_Description
+rss:Long_Description
+rss:Short_Description
+rsscategory:Long_Description
+rsschannel:Long_Description
+rsschannel:Short_Description
+rsschannelitem:Long_Description
+rsschannelitem:Short_Description
+rsscloud:Long_Description
+rssenclosure:Long_Description
+rssguid:Long_Description
+rssimage:Long_Description
+rsssource:Long_Description
+rsstextinput:Long_Description
diff --git a/docs/reference/libgfeed.types b/docs/reference/libgfeed.types
new file mode 100644 (file)
index 0000000..9fbf79e
--- /dev/null
@@ -0,0 +1,24 @@
+#include <gfeed.h>
+
+rss_get_type
+rss_channel_get_type
+rss_channel_item_get_type
+rss_category_get_type
+rss_cloud_get_type
+rss_guid_get_type
+rss_enclosure_get_type
+rss_source_get_type
+rss_image_get_type
+rss_text_input_get_type
+atom_get_type
+atom_category_get_type
+atom_common_get_type
+atom_content_get_type
+atom_date_get_type
+atom_entry_get_type
+atom_generator_get_type
+atom_id_get_type
+atom_link_get_type
+atom_person_get_type
+atom_source_get_type
+atom_text_get_type
diff --git a/docs/reference/tmpl/atom.sgml b/docs/reference/tmpl/atom.sgml
new file mode 100644 (file)
index 0000000..65c2957
--- /dev/null
@@ -0,0 +1,138 @@
+<!-- ##### SECTION Title ##### -->
+Atom
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT Atom ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG Atom:author ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:category ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:contributor ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:entry ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:generator ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:icon ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:id ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:link ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:logo ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:rights ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:subtitle ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:title ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG Atom:updated ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION atom_new ##### -->
+<para>
+
+</para>
+
+@id: 
+@title: 
+@updated: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_new_from_file ##### -->
+<para>
+
+</para>
+
+@filename: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_new_from_buffer ##### -->
+<para>
+
+</para>
+
+@buffer: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_get_xml_doc ##### -->
+<para>
+
+</para>
+
+@atom: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_save_file ##### -->
+<para>
+
+</para>
+
+@atom: 
+@filename: 
+@Returns: 
+
+
diff --git a/docs/reference/tmpl/atomcategory.sgml b/docs/reference/tmpl/atomcategory.sgml
new file mode 100644 (file)
index 0000000..fe99b5f
--- /dev/null
@@ -0,0 +1,67 @@
+<!-- ##### SECTION Title ##### -->
+AtomCategory
+
+<!-- ##### SECTION Short_Description ##### -->
+Conveys information about a category associated with an entry or feed.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT AtomCategory ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG AtomCategory:label ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomCategory:scheme ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomCategory:term ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION atom_category_new ##### -->
+<para>
+
+</para>
+
+@term: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_category_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_category_get_xml ##### -->
+<para>
+
+</para>
+
+@atom_category: 
+@xnode: 
+
+
diff --git a/docs/reference/tmpl/atomcommon.sgml b/docs/reference/tmpl/atomcommon.sgml
new file mode 100644 (file)
index 0000000..5e9748a
--- /dev/null
@@ -0,0 +1,61 @@
+<!-- ##### SECTION Title ##### -->
+AtomCommon
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT AtomCommon ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG AtomCommon:base ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomCommon:lang ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION atom_common_new ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_common_set_properties_from_xml ##### -->
+<para>
+
+</para>
+
+@atom_common: 
+@xnode: 
+
+
+<!-- ##### FUNCTION atom_common_get_xml ##### -->
+<para>
+
+</para>
+
+@atom_common: 
+@xnode: 
+
+
diff --git a/docs/reference/tmpl/atomcontent.sgml b/docs/reference/tmpl/atomcontent.sgml
new file mode 100644 (file)
index 0000000..a767f20
--- /dev/null
@@ -0,0 +1,82 @@
+<!-- ##### SECTION Title ##### -->
+AtomContent
+
+<!-- ##### SECTION Short_Description ##### -->
+Contains or links to the content of the entry.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT AtomContent ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG AtomContent:media-type ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomContent:src ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomContent:text ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomContent:type ##### -->
+<para>
+
+</para>
+
+<!-- ##### ENUM AtomContentType ##### -->
+<para>
+
+</para>
+
+@ATOM_CONTENT_TEXT: 
+@ATOM_CONTENT_HTML: 
+@ATOM_CONTENT_XHTML: 
+@ATOM_CONTENT_MEDIA: 
+
+<!-- ##### FUNCTION atom_content_new ##### -->
+<para>
+
+</para>
+
+@type: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_content_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_content_get_xml ##### -->
+<para>
+
+</para>
+
+@atom_content: 
+@xnode: 
+
+
diff --git a/docs/reference/tmpl/atomdate.sgml b/docs/reference/tmpl/atomdate.sgml
new file mode 100644 (file)
index 0000000..e63e656
--- /dev/null
@@ -0,0 +1,57 @@
+<!-- ##### SECTION Title ##### -->
+AtomDate
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT AtomDate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG AtomDate:date ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION atom_date_new ##### -->
+<para>
+
+</para>
+
+@dateTime: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_date_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_date_get_xml ##### -->
+<para>
+
+</para>
+
+@atom_date: 
+@xnode: 
+
+
diff --git a/docs/reference/tmpl/atomentry.sgml b/docs/reference/tmpl/atomentry.sgml
new file mode 100644 (file)
index 0000000..69bbe7a
--- /dev/null
@@ -0,0 +1,114 @@
+<!-- ##### SECTION Title ##### -->
+AtomEntry
+
+<!-- ##### SECTION Short_Description ##### -->
+An individual entry, acting as a container for metadata and data associated with the entry.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT AtomEntry ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG AtomEntry:author ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomEntry:category ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomEntry:content ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomEntry:contributor ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomEntry:id ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomEntry:link ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomEntry:published ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomEntry:rights ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomEntry:source ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomEntry:summary ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomEntry:title ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomEntry:updated ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION atom_entry_new ##### -->
+<para>
+
+</para>
+
+@id: 
+@title: 
+@updated: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_entry_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_entry_get_xml ##### -->
+<para>
+
+</para>
+
+@atom_entry: 
+@xnode: 
+
+
diff --git a/docs/reference/tmpl/atomgenerator.sgml b/docs/reference/tmpl/atomgenerator.sgml
new file mode 100644 (file)
index 0000000..4cf0a26
--- /dev/null
@@ -0,0 +1,67 @@
+<!-- ##### SECTION Title ##### -->
+AtomGenerator
+
+<!-- ##### SECTION Short_Description ##### -->
+Identifies the agent used to generate a feed, for debugging and other purposes.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT AtomGenerator ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG AtomGenerator:text ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomGenerator:uri ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomGenerator:version ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION atom_generator_new ##### -->
+<para>
+
+</para>
+
+@text: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_generator_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_generator_get_xml ##### -->
+<para>
+
+</para>
+
+@atom_generator: 
+@xnode: 
+
+
diff --git a/docs/reference/tmpl/atomid.sgml b/docs/reference/tmpl/atomid.sgml
new file mode 100644 (file)
index 0000000..af30ca8
--- /dev/null
@@ -0,0 +1,57 @@
+<!-- ##### SECTION Title ##### -->
+AtomID
+
+<!-- ##### SECTION Short_Description ##### -->
+A permanent, universally unique identifier for an entry or feed.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT AtomID ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG AtomID:uri ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION atom_id_new ##### -->
+<para>
+
+</para>
+
+@uri: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_id_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_id_get_xml ##### -->
+<para>
+
+</para>
+
+@atom_id: 
+@xnode: 
+
+
diff --git a/docs/reference/tmpl/atomlink.sgml b/docs/reference/tmpl/atomlink.sgml
new file mode 100644 (file)
index 0000000..e2b355f
--- /dev/null
@@ -0,0 +1,82 @@
+<!-- ##### SECTION Title ##### -->
+AtomLink
+
+<!-- ##### SECTION Short_Description ##### -->
+A reference from an entry or feed to a Web resource.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT AtomLink ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG AtomLink:href ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomLink:hreflang ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomLink:length ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomLink:rel ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomLink:title ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomLink:type ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION atom_link_new ##### -->
+<para>
+
+</para>
+
+@href: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_link_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_link_get_xml ##### -->
+<para>
+
+</para>
+
+@atom_link: 
+@xnode: 
+
+
diff --git a/docs/reference/tmpl/atomperson.sgml b/docs/reference/tmpl/atomperson.sgml
new file mode 100644 (file)
index 0000000..ce83d54
--- /dev/null
@@ -0,0 +1,67 @@
+<!-- ##### SECTION Title ##### -->
+AtomPerson
+
+<!-- ##### SECTION Short_Description ##### -->
+Describes a person, corporation, or similar entity (hereafter, 'person').
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT AtomPerson ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG AtomPerson:email ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomPerson:name ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomPerson:uri ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION atom_person_new ##### -->
+<para>
+
+</para>
+
+@name: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_person_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_person_get_xml ##### -->
+<para>
+
+</para>
+
+@atom_person: 
+@xnode: 
+
+
diff --git a/docs/reference/tmpl/atomsource.sgml b/docs/reference/tmpl/atomsource.sgml
new file mode 100644 (file)
index 0000000..cc5a8e0
--- /dev/null
@@ -0,0 +1,111 @@
+<!-- ##### SECTION Title ##### -->
+AtomSource
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT AtomSource ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG AtomSource:author ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomSource:category ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomSource:contributor ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomSource:generator ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomSource:icon ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomSource:id ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomSource:link ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomSource:logo ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomSource:rights ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomSource:subtitle ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomSource:title ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomSource:updated ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION atom_source_new ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_source_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_source_get_xml ##### -->
+<para>
+
+</para>
+
+@atom_source: 
+@xnode: 
+
+
diff --git a/docs/reference/tmpl/atomtext.sgml b/docs/reference/tmpl/atomtext.sgml
new file mode 100644 (file)
index 0000000..312f713
--- /dev/null
@@ -0,0 +1,72 @@
+<!-- ##### SECTION Title ##### -->
+AtomText
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT AtomText ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG AtomText:text ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG AtomText:type ##### -->
+<para>
+
+</para>
+
+<!-- ##### ENUM AtomTextType ##### -->
+<para>
+
+</para>
+
+@ATOM_TEXT_TEXT: 
+@ATOM_TEXT_HTML: 
+@ATOM_TEXT_XHTML: 
+
+<!-- ##### FUNCTION atom_text_new ##### -->
+<para>
+
+</para>
+
+@type: 
+@text: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_text_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION atom_text_get_xml ##### -->
+<para>
+
+</para>
+
+@atom_text: 
+@xnode: 
+
+
diff --git a/docs/reference/tmpl/gfeed.sgml b/docs/reference/tmpl/gfeed.sgml
new file mode 100644 (file)
index 0000000..927dd25
--- /dev/null
@@ -0,0 +1,21 @@
+<!-- ##### SECTION Title ##### -->
+gfeed
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
diff --git a/docs/reference/tmpl/libgfeed-unused.sgml b/docs/reference/tmpl/libgfeed-unused.sgml
new file mode 100644 (file)
index 0000000..fcfcca8
--- /dev/null
@@ -0,0 +1,1080 @@
+<!-- ##### SECTION ./tmpl/gfeed.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gfeed.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gfeed.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/gfeed.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/gfeed.sgml:Title ##### -->
+gfeed
+
+
+<!-- ##### MACRO ATOM ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_CATEGORY ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_CATEGORY_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_CATEGORY_COMMON_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_COMMON ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_COMMON_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_COMMON_COMMON_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_CONTENT ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_CONTENT_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_CONTENT_COMMON_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_DATE ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_DATE_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_DATE_COMMON_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_ENTRY ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_ENTRY_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_ENTRY_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_GENERATOR ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_GENERATOR_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_GENERATOR_COMMON_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_ID ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_ID_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_ID_COMMON_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_LINK ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_LINK_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_LINK_COMMON_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_PERSON ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_PERSON_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_PERSON_COMMON_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_SOURCE ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_SOURCE_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_SOURCE_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_TEXT ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO ATOM_TEXT_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO ATOM_TEXT_COMMON_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_CATEGORY ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_CATEGORY_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_ATOM_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_ATOM_COMMON ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_COMMON_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_ATOM_CONTENT ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_CONTENT_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_ATOM_DATE ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_DATE_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_ATOM_ENTRY ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_ENTRY_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_ATOM_GENERATOR ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_GENERATOR_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_ATOM_ID ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_ID_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_ATOM_LINK ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_LINK_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_ATOM_PERSON ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_PERSON_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_ATOM_SOURCE ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_SOURCE_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_ATOM_TEXT ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_ATOM_TEXT_COMMON_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_RSS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_RSSCATEGORY ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_RSSCATEGORY_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_RSSCHANNEL ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_RSSCHANNELITEM ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_RSSCHANNELITEM_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_RSSCHANNEL_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_RSSCLOUD ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_RSSCLOUD_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_RSSENCLOSURE ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_RSSENCLOSURE_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_RSSGUID ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_RSSGUID_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_RSSIMAGE ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_RSSIMAGE_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_RSSSOURCE ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_RSSSOURCE_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_RSSTEXTINPUT ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO IS_RSSTEXTINPUT_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO IS_RSS_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO RSS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSCATEGORY ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSCATEGORY_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO RSSCATEGORY_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSCHANNEL ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSCHANNELITEM ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSCHANNELITEM_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO RSSCHANNELITEM_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSCHANNEL_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO RSSCHANNEL_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSCLOUD ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSCLOUD_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO RSSCLOUD_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSENCLOSURE ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSENCLOSURE_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO RSSENCLOSURE_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSGUID ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSGUID_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO RSSGUID_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSIMAGE ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSIMAGE_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO RSSIMAGE_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSSOURCE ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSSOURCE_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO RSSSOURCE_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSTEXTINPUT ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSSTEXTINPUT_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO RSSTEXTINPUT_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO RSS_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO RSS_GET_CLASS ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO TYPE_ATOM ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_ATOM_CATEGORY ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_ATOM_COMMON ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_ATOM_CONTENT ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_ATOM_DATE ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_ATOM_ENTRY ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_ATOM_GENERATOR ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_ATOM_ID ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_ATOM_LINK ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_ATOM_PERSON ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_ATOM_SOURCE ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_ATOM_TEXT ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_RSS ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_RSSCATEGORY ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_RSSCHANNEL ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_RSSCHANNELITEM ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_RSSCLOUD ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_RSSENCLOSURE ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_RSSGUID ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_RSSIMAGE ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_RSSSOURCE ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TYPE_RSSTEXTINPUT ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION atom_category_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION atom_common_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION atom_content_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION atom_date_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION atom_entry_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION atom_generator_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION atom_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION atom_id_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION atom_link_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION atom_person_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION atom_source_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION atom_text_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION rss_category_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION rss_channel_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION rss_channel_item_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION rss_cloud_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION rss_enclosure_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION rss_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION rss_guid_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION rss_image_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION rss_source_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+<!-- ##### FUNCTION rss_text_input_get_type ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
diff --git a/docs/reference/tmpl/rss.sgml b/docs/reference/tmpl/rss.sgml
new file mode 100644 (file)
index 0000000..65306a8
--- /dev/null
@@ -0,0 +1,75 @@
+<!-- ##### SECTION Title ##### -->
+Rss
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT Rss ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG Rss:channel ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION rss_new ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_new_from_file ##### -->
+<para>
+
+</para>
+
+@filename: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_new_from_buffer ##### -->
+<para>
+
+</para>
+
+@buffer: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_get_xml_doc ##### -->
+<para>
+
+</para>
+
+@rss: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_save_file ##### -->
+<para>
+
+</para>
+
+@rss: 
+@filename: 
+@Returns: 
+
+
diff --git a/docs/reference/tmpl/rsscategory.sgml b/docs/reference/tmpl/rsscategory.sgml
new file mode 100644 (file)
index 0000000..5bf4aba
--- /dev/null
@@ -0,0 +1,62 @@
+<!-- ##### SECTION Title ##### -->
+RssCategory
+
+<!-- ##### SECTION Short_Description ##### -->
+Specify one or more categories that the channel belongs to.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT RssCategory ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG RssCategory:domain ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssCategory:location ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION rss_category_new ##### -->
+<para>
+
+</para>
+
+@location: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_category_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_category_get_xml ##### -->
+<para>
+
+</para>
+
+@rss_category: 
+@Returns: 
+
+
diff --git a/docs/reference/tmpl/rsschannel.sgml b/docs/reference/tmpl/rsschannel.sgml
new file mode 100644 (file)
index 0000000..7ee0c19
--- /dev/null
@@ -0,0 +1,395 @@
+<!-- ##### SECTION Title ##### -->
+RssChannel
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO RSSCHANNEL_DAY_MONDAY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_DAY_TUESDAY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_DAY_WEDNESDAY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_DAY_THURSDAY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_DAY_FRIDAY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_DAY_SATURDAY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_DAY_SUNDAY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_0 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_6 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_8 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_10 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_11 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_12 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_13 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_14 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_15 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_16 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_17 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_18 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_19 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_20 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_21 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_22 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO RSSCHANNEL_HOUR_23 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### STRUCT RssChannel ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG RssChannel:cloud ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:copyright ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:description ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:docs ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:generator ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:image ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:language ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:last-build-date ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:link ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:managing-editor ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:pub-date ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:skip-days ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:skip-hours ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:text-input ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:title ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:ttl ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannel:webmaster ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION rss_channel_new ##### -->
+<para>
+
+</para>
+
+@title: 
+@link: 
+@description: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_channel_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_channel_add_category ##### -->
+<para>
+
+</para>
+
+@rss_channel: 
+@rss_category: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_channel_get_categories ##### -->
+<para>
+
+</para>
+
+@rss_channel: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_channel_add_item ##### -->
+<para>
+
+</para>
+
+@rss_channel: 
+@rss_channel_item: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_channel_remove_item ##### -->
+<para>
+
+</para>
+
+@rss_channel: 
+@rss_channel_item: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_channel_get_xml ##### -->
+<para>
+
+</para>
+
+@rss_channel: 
+@Returns: 
+
+
diff --git a/docs/reference/tmpl/rsschannelitem.sgml b/docs/reference/tmpl/rsschannelitem.sgml
new file mode 100644 (file)
index 0000000..b73655a
--- /dev/null
@@ -0,0 +1,117 @@
+<!-- ##### SECTION Title ##### -->
+RssChannelItem
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT RssChannelItem ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG RssChannelItem:author ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannelItem:comments ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannelItem:description ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannelItem:enclosure ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannelItem:guid ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannelItem:link ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannelItem:pub-date ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannelItem:source ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssChannelItem:title ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION rss_channel_item_new ##### -->
+<para>
+
+</para>
+
+@title: 
+@description: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_channel_item_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_channel_item_add_category ##### -->
+<para>
+
+</para>
+
+@rss_channel_item: 
+@rss_category: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_channel_item_get_categories ##### -->
+<para>
+
+</para>
+
+@rss_channel_item: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_channel_item_get_xml ##### -->
+<para>
+
+</para>
+
+@rss_channel_item: 
+@Returns: 
+
+
diff --git a/docs/reference/tmpl/rsscloud.sgml b/docs/reference/tmpl/rsscloud.sgml
new file mode 100644 (file)
index 0000000..f5e27ca
--- /dev/null
@@ -0,0 +1,81 @@
+<!-- ##### SECTION Title ##### -->
+RssCloud
+
+<!-- ##### SECTION Short_Description ##### -->
+Allows processes to register with a cloud to be notified of updates to the channel, implementing a lightweight publish-subscribe protocol for RSS feeds.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT RssCloud ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG RssCloud:domain ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssCloud:path ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssCloud:port ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssCloud:protocol ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssCloud:register-procedure ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION rss_cloud_new ##### -->
+<para>
+
+</para>
+
+@domain: 
+@port: 
+@path: 
+@registerProcedure: 
+@protocol: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_cloud_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_cloud_get_xml ##### -->
+<para>
+
+</para>
+
+@rss_cloud: 
+@Returns: 
+
+
diff --git a/docs/reference/tmpl/rssenclosure.sgml b/docs/reference/tmpl/rssenclosure.sgml
new file mode 100644 (file)
index 0000000..8d63b91
--- /dev/null
@@ -0,0 +1,69 @@
+<!-- ##### SECTION Title ##### -->
+RssEnclosure
+
+<!-- ##### SECTION Short_Description ##### -->
+Describes a media object that is attached to the item.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT RssEnclosure ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG RssEnclosure:length ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssEnclosure:type ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssEnclosure:url ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION rss_enclosure_new ##### -->
+<para>
+
+</para>
+
+@url: 
+@length: 
+@type: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_enclosure_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_enclosure_get_xml ##### -->
+<para>
+
+</para>
+
+@rss_enclosure: 
+@Returns: 
+
+
diff --git a/docs/reference/tmpl/rssguid.sgml b/docs/reference/tmpl/rssguid.sgml
new file mode 100644 (file)
index 0000000..44933c6
--- /dev/null
@@ -0,0 +1,62 @@
+<!-- ##### SECTION Title ##### -->
+RssGuid
+
+<!-- ##### SECTION Short_Description ##### -->
+A string that uniquely identifies the item (Globally Unique Identifier).
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT RssGuid ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG RssGuid:guid ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssGuid:is-permalink ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION rss_guid_new ##### -->
+<para>
+
+</para>
+
+@guid: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_guid_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_guid_get_xml ##### -->
+<para>
+
+</para>
+
+@rss_guid: 
+@Returns: 
+
+
diff --git a/docs/reference/tmpl/rssimage.sgml b/docs/reference/tmpl/rssimage.sgml
new file mode 100644 (file)
index 0000000..bd17c55
--- /dev/null
@@ -0,0 +1,84 @@
+<!-- ##### SECTION Title ##### -->
+RssImage
+
+<!-- ##### SECTION Short_Description ##### -->
+Specifies a GIF, JPEG or PNG image that can be displayed with the channel.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT RssImage ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG RssImage:description ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssImage:height ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssImage:link ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssImage:title ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssImage:url ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssImage:width ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION rss_image_new ##### -->
+<para>
+
+</para>
+
+@url: 
+@title: 
+@link: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_image_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_image_get_xml ##### -->
+<para>
+
+</para>
+
+@rss_image: 
+@Returns: 
+
+
diff --git a/docs/reference/tmpl/rsssource.sgml b/docs/reference/tmpl/rsssource.sgml
new file mode 100644 (file)
index 0000000..9eb3461
--- /dev/null
@@ -0,0 +1,63 @@
+<!-- ##### SECTION Title ##### -->
+RssSource
+
+<!-- ##### SECTION Short_Description ##### -->
+The RSS channel that the item came from.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT RssSource ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG RssSource:title ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssSource:url ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION rss_source_new ##### -->
+<para>
+
+</para>
+
+@title: 
+@url: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_source_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_source_get_xml ##### -->
+<para>
+
+</para>
+
+@rss_source: 
+@Returns: 
+
+
diff --git a/docs/reference/tmpl/rsstextinput.sgml b/docs/reference/tmpl/rsstextinput.sgml
new file mode 100644 (file)
index 0000000..ffab614
--- /dev/null
@@ -0,0 +1,75 @@
+<!-- ##### SECTION Title ##### -->
+RssTextInput
+
+<!-- ##### SECTION Short_Description ##### -->
+Specifies a text input box that can be displayed with the channel.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT RssTextInput ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG RssTextInput:description ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssTextInput:link ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssTextInput:name ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG RssTextInput:title ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION rss_text_input_new ##### -->
+<para>
+
+</para>
+
+@title: 
+@description: 
+@name: 
+@link: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_text_input_new_from_xml ##### -->
+<para>
+
+</para>
+
+@xnode: 
+@Returns: 
+
+
+<!-- ##### FUNCTION rss_text_input_get_xml ##### -->
+<para>
+
+</para>
+
+@rss_text_input: 
+@Returns: 
+
+
diff --git a/docs/reference/version.xml.in b/docs/reference/version.xml.in
new file mode 100644 (file)
index 0000000..c5d0fd6
--- /dev/null
@@ -0,0 +1,2 @@
+@PACKAGE_VERSION@
+
diff --git a/libgfeed.pc.in b/libgfeed.pc.in
new file mode 100644 (file)
index 0000000..8aa176d
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: @PACKAGE_NAME@
+Description: Library to create RSS and Atom feed
+Version: @PACKAGE_VERSION@
+Requires: glib-2.0 gobject-2.0 libxml-2.0
+Libs: -L${libdir} -lgfeed
+Cflags: -I${includedir}/libgfeed
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..c7eb240
--- /dev/null
@@ -0,0 +1,56 @@
+LIBS = $(GFEED_LIBS)
+
+AM_CPPFLAGS = $(GFEED_CFLAGS)
+
+lib_LTLIBRARIES = libgfeed.la
+
+libgfeed_la_SOURCES = rss.c \
+                      rsschannel.c \
+                      rsschannelitem.c \
+                      rsscategory.c \
+                      rsscloud.c \
+                      rssimage.c \
+                      rsstextinput.c \
+                      rssenclosure.c \
+                      rssguid.c \
+                      rsssource.c \
+                      atom.c \
+                      atomcommon.c \
+                      atomtext.c \
+                      atomperson.c \
+                      atomdate.c \
+                      atomid.c \
+                      atomcategory.c \
+                      atomgenerator.c \
+                      atomlink.c \
+                      atomsource.c \
+                      atomentry.c \
+                      atomcontent.c
+
+libgfeed_la_LDFLAGS = -no-undefined
+
+libgfeed_include_HEADERS = gfeed.h \
+                  rss.h \
+                  rsschannel.h \
+                  rsschannelitem.h \
+                  rsscategory.h \
+                  rsscloud.h \
+                  rssimage.h \
+                  rsstextinput.h \
+                  rssenclosure.h \
+                  rssguid.h \
+                  rsssource.h \
+                  atom.h \
+                  atomcommon.h \
+                  atomtext.h \
+                  atomperson.h \
+                  atomdate.h \
+                  atomid.h \
+                  atomcategory.h \
+                  atomgenerator.h \
+                  atomlink.h \
+                  atomsource.h \
+                  atomentry.h \
+                  atomcontent.h
+
+libgfeed_includedir = $(includedir)/libgfeed
diff --git a/src/atom.c b/src/atom.c
new file mode 100644 (file)
index 0000000..c008568
--- /dev/null
@@ -0,0 +1,810 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifdef HAVE_CONFIG_H
+       #include <config.h>
+#endif
+
+#include <libxml/xpath.h>
+
+#include "atom.h"
+#include "atomperson.h"
+#include "atomcategory.h"
+#include "atomgenerator.h"
+#include "atomlink.h"
+#include "atomentry.h"
+
+enum
+{
+       PROP_0,
+       PROP_AUTHOR,
+       PROP_CATEGORY,
+       PROP_CONTRIBUTOR,
+       PROP_GENERATOR,
+       PROP_ICON,
+       PROP_ID,
+       PROP_LINK,
+       PROP_LOGO,
+       PROP_RIGHTS,
+       PROP_SUBTITLE,
+       PROP_TITLE,
+       PROP_UPDATED,
+       PROP_ENTRY
+};
+
+static void atom_class_init (AtomClass *klass);
+static void atom_init (Atom *atom);
+
+static void atom_set_property (GObject *object,
+                               guint property_id,
+                               const GValue *value,
+                               GParamSpec *pspec);
+static void atom_get_property (GObject *object,
+                               guint property_id,
+                               GValue *value,
+                               GParamSpec *pspec);
+
+static Atom *parse_xml (xmlDoc *xdoc);
+
+
+#define ATOM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM, AtomPrivate))
+
+typedef struct _AtomPrivate AtomPrivate;
+struct _AtomPrivate
+       {
+               GList *author,
+                     *category,
+                     *contributor,
+                     *entry;
+               AtomGenerator *generator;
+               AtomID *icon,
+                      *id,
+                      *logo;
+               AtomLink *link;
+               AtomText *title,
+                        *rights,
+                        *subtitle;
+               AtomDate *updated;
+       };
+
+GType
+atom_get_type (void)
+{
+       static GType atom_type = 0;
+
+       if (!atom_type)
+               {
+                       static const GTypeInfo atom_info =
+                       {
+                               sizeof (AtomClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (Atom),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_init,
+                               NULL
+                       };
+
+                       atom_type = g_type_register_static (TYPE_ATOM_COMMON, "Atom",
+                                                           &atom_info, 0);
+               }
+
+       return atom_type;
+}
+
+static void
+atom_class_init (AtomClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomPrivate));
+
+       object_class->set_property = atom_set_property;
+       object_class->get_property = atom_get_property;
+
+       g_object_class_install_property (object_class, PROP_AUTHOR,
+                                        g_param_spec_pointer ("author",
+                                                              "Author",
+                                                              "A #GList of #AtomPerson objects that indicates the author of the entry or feed.",
+                                                              G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_CATEGORY,
+                                        g_param_spec_pointer ("category",
+                                                              "Category",
+                                                              "A #GList of #AtomCategory objects convey information about a category associated with an entry or feed.",
+                                                              G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_CONTRIBUTOR,
+                                        g_param_spec_pointer ("contributor",
+                                                              "Contributor",
+                                                              "A #GList of #AtomPerson objects that indicate a person or other entity who contributed to the entry or feed.",
+                                                              G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_GENERATOR,
+                                        g_param_spec_object ("generator",
+                                                             "Generato",
+                                                             "An #AtomGenerator object that identifies the agent used to generate a feed, for debugging and other purposes.",
+                                                             TYPE_ATOM_GENERATOR,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_ICON,
+                                        g_param_spec_object ("icon",
+                                                             "Icon",
+                                                             "An #AtomID object that contains an IRI reference [RFC3987] that identifies an image that provides iconic visual identification for a feed.",
+                                                             TYPE_ATOM_ID,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_ID,
+                                        g_param_spec_object ("id",
+                                                             "Id",
+                                                             "An #AtomID object that conveys a permanent, universally unique identifier for an entry or feed.",
+                                                             TYPE_ATOM_ID,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_LINK,
+                                        g_param_spec_object ("link",
+                                                             "Link",
+                                                             "An #AtomLink object that defines a reference from an entry or feed to a Web resource.",
+                                                             TYPE_ATOM_LINK,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_LOGO,
+                                        g_param_spec_object ("logo",
+                                                             "Logo",
+                                                             "An #AtonID object that contains an IRI reference [RFC3987] that identifies an image that provides visual identification for a feed.",
+                                                             TYPE_ATOM_ID,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_RIGHTS,
+                                        g_param_spec_object ("rights",
+                                                             "Rights",
+                                                             "An #AtomText object that conveys information about rights held in and over an entry or feed.",
+                                                             TYPE_ATOM_TEXT,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_SUBTITLE,
+                                        g_param_spec_object ("subtitle",
+                                                             "Subtitle",
+                                                             "An #AtomText object that conveys a human-readable description or subtitle for a feed.",
+                                                             TYPE_ATOM_TEXT,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_TITLE,
+                                        g_param_spec_object ("title",
+                                                             "Title",
+                                                             "An #AtomText object that conveys a human-readable title for an entry or feed.",
+                                                             TYPE_ATOM_TEXT,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_UPDATED,
+                                        g_param_spec_object ("updated",
+                                                             "Updated",
+                                                             "An #AtomDate object indicating the most recent instant in time when an entry or feed was modified in a way the publisher considers significant.",
+                                                             TYPE_ATOM_DATE,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_ENTRY,
+                                        g_param_spec_pointer ("entry",
+                                                              "Entry",
+                                                              "A #GList of #AtomEntry.",
+                                                              G_PARAM_READWRITE));
+}
+
+static void
+atom_init (Atom *atom)
+{
+}
+
+/**
+ * atom_new:
+ * @id: an #AtomID object that conveys a permanent, universally unique identifier for an entry or feed.
+ * @title: an #AtomText object that conveys a human-readable title for an entry or feed.
+ * @updated: an #AtomDate object indicating the most recent instant in time when an entry or feed was modified in a way the publisher considers significant.
+ *
+ * Returns: the newly created #Atom object.
+ */
+Atom
+*atom_new (AtomID *id, AtomText *title, AtomDate *updated)
+{
+       Atom *atom = ATOM (g_object_new (atom_get_type (), NULL));
+
+       g_object_set (G_OBJECT (atom),
+                     "id", id,
+                     "title", title,
+                     "updated", updated,
+                     NULL);
+
+       return atom;
+}
+
+/**
+ * atom_new_from_file:
+ * @filename:
+ *
+ * Returns: the newly created #Atom object.
+ */
+Atom
+*atom_new_from_file (const gchar *filename)
+{
+       Atom *atom = NULL;
+
+       xmlDoc *xdoc = xmlParseFile (filename);
+
+       atom = parse_xml (xdoc);
+
+       return atom;
+}
+
+/**
+ * atom_new_from_buffer:
+ * @buffer: a pointer to an array of #gchar.
+ *
+ * Returns: the newly created #Atom object.
+ */
+Atom
+*atom_new_from_buffer (const gchar *buffer)
+{
+       Atom *atom = NULL;
+
+       xmlDoc *xdoc = xmlParseDoc (buffer);
+
+       atom = parse_xml (xdoc);
+
+       return atom;
+}
+
+/**
+ * atom_get_xml_doc:
+ * @atom: an #Atom object.
+ *
+ * Returns: the #xmlDoc correspondent to the entire #Atom object.
+ */
+xmlDoc
+*atom_get_xml_doc (Atom *atom)
+{
+       xmlNode *xnode;
+       GList *lst;
+
+       AtomPrivate *priv = ATOM_GET_PRIVATE (atom);
+
+       xmlDoc *xdoc = xmlNewDoc ((const xmlChar *)"1.0");
+       xmlNode *xroot = xmlNewNode (NULL, (const xmlChar *)"feed");
+
+  /* adding root element */
+  if (xroot == NULL) return NULL;
+
+  xmlSetProp (xroot, (const xmlChar *)"xmlns", (const xmlChar *)"http://www.w3.org/2005/Atom");
+  xmlDocSetRootElement (xdoc, xroot);
+
+       lst = g_list_first (priv->author);
+       while (lst != NULL)
+               {
+                       if (IS_ATOM_PERSON (lst->data))
+                               {
+                                       xnode = xmlNewNode (NULL, (const xmlChar *)"author");
+                                       xmlAddChild (xroot, xnode);
+                                       atom_person_get_xml (ATOM_PERSON (lst->data), xnode);
+                               }
+
+                       lst = g_list_next (lst);
+               }
+
+       lst = g_list_first (priv->category);
+       while (lst != NULL)
+               {
+                       if (IS_ATOM_CATEGORY (lst->data))
+                               {
+                                       xnode = xmlNewNode (NULL, (const xmlChar *)"category");
+                                       xmlAddChild (xroot, xnode);
+                                       atom_category_get_xml (ATOM_CATEGORY (lst->data), xnode);
+                               }
+
+                       lst = g_list_next (lst);
+               }
+
+       lst = g_list_first (priv->contributor);
+       while (lst != NULL)
+               {
+                       if (IS_ATOM_PERSON (lst->data))
+                               {
+                                       xnode = xmlNewNode (NULL, (const xmlChar *)"contributor");
+                                       xmlAddChild (xroot, xnode);
+                                       atom_person_get_xml (ATOM_PERSON (lst->data), xnode);
+                               }
+
+                       lst = g_list_next (lst);
+               }
+
+       if (priv->generator != NULL)
+               {
+                       xnode = xmlNewNode (NULL, (const xmlChar *)"generator");
+                       xmlAddChild (xroot, xnode);
+                       atom_generator_get_xml (priv->generator, xnode);                
+               }
+
+       if (priv->icon != NULL)
+               {
+                       xnode = xmlNewNode (NULL, (const xmlChar *)"icon");
+                       xmlAddChild (xroot, xnode);
+                       atom_id_get_xml (priv->icon, xnode);
+               }
+
+       if (priv->id != NULL)
+               {
+                       xnode = xmlNewNode (NULL, (const xmlChar *)"id");
+                       xmlAddChild (xroot, xnode);
+                       atom_id_get_xml (priv->id, xnode);
+               }
+       else
+               {
+                       /* TO DO */
+                       return NULL;
+               }
+
+       if (priv->link != NULL)
+               {
+                       xnode = xmlNewNode (NULL, (const xmlChar *)"link");
+                       xmlAddChild (xroot, xnode);
+                       atom_link_get_xml (priv->link, xnode);
+               }
+
+       if (priv->logo != NULL)
+               {
+                       xnode = xmlNewNode (NULL, (const xmlChar *)"logo");
+                       xmlAddChild (xroot, xnode);
+                       atom_id_get_xml (priv->logo, xnode);
+               }
+
+       if (priv->rights != NULL)
+               {
+                       xnode = xmlNewNode (NULL, (const xmlChar *)"rights");
+                       xmlAddChild (xroot, xnode);
+                       atom_text_get_xml (priv->rights, xnode);
+               }
+
+       if (priv->subtitle != NULL)
+               {
+                       xnode = xmlNewNode (NULL, (const xmlChar *)"subtitle");
+                       xmlAddChild (xroot, xnode);
+                       atom_text_get_xml (priv->subtitle, xnode);
+               }
+
+       if (priv->title != NULL)
+               {
+                       xnode = xmlNewNode (NULL, (const xmlChar *)"title");
+                       xmlAddChild (xroot, xnode);
+                       atom_text_get_xml (priv->title, xnode);
+               }
+       else
+               {
+                       /* TO DO */
+                       return NULL;
+               }
+
+       if (priv->updated != NULL)
+               {
+                       xnode = xmlNewNode (NULL, (const xmlChar *)"updated");
+                       xmlAddChild (xroot, xnode);
+                       atom_date_get_xml (priv->updated, xnode);
+               }
+       else
+               {
+                       /* TO DO */
+                       return NULL;
+               }
+
+       lst = g_list_first (priv->entry);
+       while (lst != NULL)
+               {
+                       if (IS_ATOM_ENTRY (lst->data))
+                               {
+                                       xnode = xmlNewNode (NULL, (const xmlChar *)"entry");
+                                       xmlAddChild (xroot, xnode);
+                                       atom_entry_get_xml (ATOM_ENTRY (lst->data), xnode);
+                               }
+
+                       lst = g_list_next (lst);
+               }
+
+       return xdoc;
+}
+
+/**
+ * atom_save_file:
+ * @atom: an #Atom object.
+ * @filename:
+ *
+ */
+gboolean
+atom_save_file (Atom *atom, const gchar *filename)
+{
+       return (xmlSaveFileEnc (filename, atom_get_xml_doc (atom), "utf-8") > -1);
+}
+
+static void
+atom_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       GObject *obj;
+
+       Atom *atom = ATOM (object);
+
+       AtomPrivate *priv = ATOM_GET_PRIVATE (atom);
+
+       switch (property_id)
+               {
+                       case PROP_AUTHOR:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->author = (GList *)g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (GList));
+                                       }
+                               break;
+
+                       case PROP_CATEGORY:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->category = (GList *)g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (GList));
+                                       }
+                               break;
+
+                       case PROP_CONTRIBUTOR:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->contributor = (GList *)g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (GList));
+                                       }
+                               break;
+
+                       case PROP_GENERATOR:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_GENERATOR (g_value_get_object (value)))
+                                       {
+                                               priv->generator = (AtomGenerator *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_ICON:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_ID (g_value_get_object (value)))
+                                       {
+                                               priv->icon = (AtomID *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_ID:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_ID (g_value_get_object (value)))
+                                       {
+                                               priv->id = (AtomID *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_LINK:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_LINK (g_value_get_object (value)))
+                                       {
+                                               priv->link = (AtomLink *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_LOGO:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_ID (g_value_get_object (value)))
+                                       {
+                                               priv->logo = (AtomID *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_RIGHTS:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_TEXT (g_value_get_object (value)))
+                                       {
+                                               priv->rights = (AtomText *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_SUBTITLE:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_TEXT (g_value_get_object (value)))
+                                       {
+                                               priv->subtitle = (AtomText *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_TITLE:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_TEXT (g_value_get_object (value)))
+                                       {
+                                               priv->title = (AtomText *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_UPDATED:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_DATE (g_value_get_object (value)))
+                                       {
+                                               priv->updated = (AtomDate *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_ENTRY:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->entry = (GList *)g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (GList));
+                                       }
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       Atom *atom = ATOM (object);
+
+       AtomPrivate *priv = ATOM_GET_PRIVATE (atom);
+       
+       switch (property_id)
+               {
+                       case PROP_AUTHOR:
+                               g_value_set_pointer (value, priv->author);
+                               break;
+
+                       case PROP_CATEGORY:
+                               g_value_set_pointer (value, priv->category);
+                               break;
+
+                       case PROP_CONTRIBUTOR:
+                               g_value_set_pointer (value, priv->contributor);
+                               break;
+
+                       case PROP_GENERATOR:
+                               g_value_set_pointer (value, priv->generator);
+                               break;
+
+                       case PROP_ICON:
+                               g_value_set_object (value, priv->icon);
+                               break;
+
+                       case PROP_ID:
+                               g_value_set_object (value, priv->id);
+                               break;
+
+                       case PROP_LINK:
+                               g_value_set_object (value, priv->link);
+                               break;
+
+                       case PROP_LOGO:
+                               g_value_set_object (value, priv->logo);
+                               break;
+
+                       case PROP_RIGHTS:
+                               g_value_set_object (value, priv->rights);
+                               break;
+
+                       case PROP_SUBTITLE:
+                               g_value_set_object (value, priv->subtitle);
+                               break;
+
+                       case PROP_TITLE:
+                               g_value_set_object (value, priv->title);
+                               break;
+
+                       case PROP_UPDATED:
+                               g_value_set_object (value, priv->updated);
+                               break;
+
+                       case PROP_ENTRY:
+                               g_value_set_object (value, priv->entry);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static Atom
+*parse_xml (xmlDoc *xdoc)
+{
+       Atom *atom;
+
+       if (xdoc != NULL)
+               {
+                       xmlNode *cur = xmlDocGetRootElement (xdoc);
+                       if (cur != NULL)
+                               {
+                                       if (xmlStrcmp (cur->name, (const xmlChar *)"feed") == 0)
+                                               {
+                                                       xmlNsPtr *xmlns = xmlGetNsList (xdoc, cur);
+                                                       if (xmlns != NULL && xmlStrcmp (xmlns[0]->href, (const xmlChar *)"http://www.w3.org/2005/Atom") == 0)
+                                                               {
+                                                                       if (cur->children != NULL)
+                                                                               {
+                                                                                       AtomID *id = NULL;
+                                                                                       AtomText *title = NULL;
+                                                                                       AtomDate *updated = NULL;
+                                                                               
+                                                                                       xmlXPathObjectPtr xpresult;
+                                                                                       xmlXPathContextPtr xpcontext = xmlXPathNewContext (xdoc);
+
+                                                                                       xmlXPathRegisterNs (xpcontext, (const xmlChar *)"atom", xmlns[0]->href);
+
+                                                                                       /* searching for id */
+                                                                                       xpcontext->node = cur;
+                                                                                       xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::atom:id", xpcontext);
+                                                                                       if (xpresult == NULL || xpresult->nodesetval == NULL || xpresult->nodesetval->nodeNr != 1)
+                                                                                               {
+                                                                                                       g_critical ("Atom document must contain one and only id element.");
+                                                                                               }
+                                                                                       else
+                                                                                               {
+                                                                                                       id = atom_id_new_from_xml (xpresult->nodesetval->nodeTab[0]);
+                                                                                                       if (id == NULL)
+                                                                                                               {
+                                                                                                                       g_critical ("Invalid id element.");
+                                                                                                               }
+                                                                                               }
+
+                                                                                       /* searching for title */
+                                                                                       xpcontext->node = cur;
+                                                                                       xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::atom:title", xpcontext);
+                                                                                       if (xpresult == NULL || xpresult->nodesetval == NULL || xpresult->nodesetval->nodeNr != 1)
+                                                                                               {
+                                                                                                       g_critical ("Atom document must contain one and only title element.");
+                                                                                               }
+                                                                                       else
+                                                                                               {
+                                                                                                       title = atom_text_new_from_xml (xpresult->nodesetval->nodeTab[0]);
+                                                                                                       if (title == NULL)
+                                                                                                               {
+                                                                                                                       g_critical ("Invalid title element.");
+                                                                                                               }
+                                                                                               }
+
+                                                                                       /* searching for updated */
+                                                                                       xpcontext->node = cur;
+                                                                                       xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::atom:updated", xpcontext);
+                                                                                       if (xpresult == NULL || xpresult->nodesetval == NULL || xpresult->nodesetval->nodeNr != 1)
+                                                                                               {
+                                                                                                       g_critical ("Atom document must contain one and only updated element.");
+                                                                                               }
+                                                                                       else
+                                                                                               {
+                                                                                                       updated = atom_date_new_from_xml (xpresult->nodesetval->nodeTab[0]);
+                                                                                                       if (updated == NULL)
+                                                                                                               {
+                                                                                                                       g_critical ("Invalid updated element.");
+                                                                                                               }
+                                                                                               }
+
+                                                                                       if (id != NULL && title != NULL && updated != NULL)
+                                                                                               {
+                                                                                                       atom = atom_new (id, title, updated);
+
+                                                                                                       AtomPrivate *priv = ATOM_GET_PRIVATE (atom);
+
+                                                                                                       cur = cur->children;
+                                                                                                       while (cur != NULL)
+                                                                                                               {
+                                                                                                                       if (xmlStrcmp (cur->name, (const xmlChar *)"author") == 0)
+                                                                                                                               {
+                                                                                                                                       AtomPerson *ap = atom_person_new_from_xml (cur);
+                                                                                                                                       if (ap != NULL)
+                                                                                                                                               {
+                                                                                                                                                       priv->author = g_list_append (priv->author, ap);
+                                                                                                                                               }
+                                                                                                                               }
+                                                                                                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"category") == 0)
+                                                                                                                               {
+                                                                                                                                       AtomCategory *ac = atom_category_new_from_xml (cur);
+                                                                                                                                       if (ac != NULL)
+                                                                                                                                               {
+                                                                                                                                                       priv->category = g_list_append (priv->category, ac);
+                                                                                                                                               }
+                                                                                                                               }
+                                                                                                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"contributor") == 0)
+                                                                                                                               {
+                                                                                                                                       AtomPerson *ap = atom_person_new_from_xml (cur);
+                                                                                                                                       if (ap != NULL)
+                                                                                                                                               {
+                                                                                                                                                       priv->contributor = g_list_append (priv->contributor, ap);
+                                                                                                                                               }
+                                                                                                                               }
+                                                                                                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"generator") == 0)
+                                                                                                                               {
+                                                                                                                                       AtomGenerator *ag = atom_generator_new_from_xml (cur);
+                                                                                                                                       if (ag != NULL)
+                                                                                                                                               {
+                                                                                                                                                       priv->generator = ag;
+                                                                                                                                               }
+                                                                                                                               }
+                                                                                                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"icon") == 0)
+                                                                                                                               {
+                                                                                                                                       AtomID *icon = atom_id_new_from_xml (cur);
+                                                                                                                                       if (icon == NULL)
+                                                                                                                                               {
+                                                                                                                                                       priv->icon = icon;
+                                                                                                                                               }
+                                                                                                                               }
+                                                                                                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"link") == 0)
+                                                                                                                               {
+                                                                                                                                       AtomLink *link = atom_link_new_from_xml (cur);
+                                                                                                                                       if (link == NULL)
+                                                                                                                                               {
+                                                                                                                                                       priv->link = link;
+                                                                                                                                               }
+                                                                                                                               }
+                                                                                                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"logo") == 0)
+                                                                                                                               {
+                                                                                                                                       AtomID *logo = atom_id_new_from_xml (cur);
+                                                                                                                                       if (logo == NULL)
+                                                                                                                                               {
+                                                                                                                                                       priv->logo = logo;
+                                                                                                                                               }
+                                                                                                                               }
+                                                                                                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"rights") == 0)
+                                                                                                                               {
+                                                                                                                                       AtomText *rights = atom_text_new_from_xml (cur);
+                                                                                                                                       if (rights != NULL)
+                                                                                                                                               {
+                                                                                                                                                       priv->rights = rights;
+                                                                                                                                               }
+                                                                                                                               }
+                                                                                                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"subtitle") == 0)
+                                                                                                                               {
+                                                                                                                                       AtomText *subtitle = atom_text_new_from_xml (cur);
+                                                                                                                                       if (subtitle != NULL)
+                                                                                                                                               {
+                                                                                                                                                       priv->subtitle = subtitle;
+                                                                                                                                               }
+                                                                                                                               }
+                                                                                                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"entry") == 0)
+                                                                                                                               {
+                                                                                                                                       AtomEntry *ae = atom_entry_new_from_xml (cur);
+                                                                                                                                       if (ae != NULL)
+                                                                                                                                               {
+                                                                                                                                                       priv->entry = g_list_append (priv->entry, ae);
+                                                                                                                                               }
+                                                                                                                               }
+
+                                                                                                                       cur = cur->next;
+                                                                                                               }
+                                                                                               }
+                                                                               }
+                                                                       else
+                                                                               {
+                                                                                       g_critical ("Empty atom document.");
+                                                                               }
+                                                               }
+                                                       else
+                                                               {
+                                                                       g_critical ("Wrong atom version.");
+                                                               }
+                                               }
+                                       else
+                                               {
+                                                       g_critical ("XML document is not an atom feed document.");
+                                               }
+                               }
+                       else
+                               {
+                                       g_critical ("Empty document.");
+                               }
+               }
+
+       return atom;
+}
diff --git a/src/atom.h b/src/atom.h
new file mode 100644 (file)
index 0000000..19247db
--- /dev/null
@@ -0,0 +1,70 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_H__
+#define __ATOM_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+#include "atomcommon.h"
+#include "atomid.h"
+#include "atomtext.h"
+#include "atomdate.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM                 (atom_get_type ())
+#define ATOM(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM, Atom))
+#define ATOM_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM, AtomClass))
+#define IS_ATOM(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM))
+#define IS_ATOM_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM))
+#define ATOM_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM, AtomClass))
+
+
+typedef struct _Atom Atom;
+typedef struct _AtomClass AtomClass;
+
+struct _Atom
+       {
+               AtomCommon parent;
+       };
+
+struct _AtomClass
+       {
+               AtomCommonClass parent_class;
+       };
+
+GType atom_get_type (void) G_GNUC_CONST;
+
+Atom *atom_new (AtomID *id, AtomText *title, AtomDate *updated);
+Atom *atom_new_from_file (const gchar *filename);
+Atom *atom_new_from_buffer (const gchar *buffer);
+
+xmlDoc *atom_get_xml_doc (Atom *atom);
+gboolean atom_save_file (Atom *atom, const gchar *filename);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_H__ */
diff --git a/src/atomcategory.c b/src/atomcategory.c
new file mode 100644 (file)
index 0000000..c986d0d
--- /dev/null
@@ -0,0 +1,269 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include "atomcategory.h"
+
+enum
+{
+       PROP_0,
+       PROP_TERM,
+       PROP_SCHEME,
+       PROP_LABEL,
+};
+
+static void atom_category_class_init (AtomCategoryClass *klass);
+static void atom_category_init (AtomCategory *atom_category);
+
+static void atom_category_set_property (GObject *object,
+                                    guint property_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec);
+static void atom_category_get_property (GObject *object,
+                                    guint property_id,
+                                    GValue *value,
+                                    GParamSpec *pspec);
+
+#define ATOM_CATEGORY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM_CATEGORY, AtomCategoryPrivate))
+
+typedef struct _AtomCategoryPrivate AtomCategoryPrivate;
+struct _AtomCategoryPrivate
+       {
+               gchar *term,
+                     *scheme,
+                     *label;
+       };
+
+GType
+atom_category_get_type (void)
+{
+       static GType atom_category_type = 0;
+
+       if (!atom_category_type)
+               {
+                       static const GTypeInfo atom_category_info =
+                       {
+                               sizeof (AtomCategoryClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_category_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (AtomCategory),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_category_init,
+                               NULL
+                       };
+
+                       atom_category_type = g_type_register_static (TYPE_ATOM_COMMON, "AtomCategory",
+                                                                    &atom_category_info, 0);
+               }
+
+       return atom_category_type;
+}
+
+static void
+atom_category_class_init (AtomCategoryClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomCategoryPrivate));
+
+       object_class->set_property = atom_category_set_property;
+       object_class->get_property = atom_category_get_property;
+
+       g_object_class_install_property (object_class, PROP_TERM,
+                                        g_param_spec_string ("term",
+                                                             "Term",
+                                                             "A string that identifies the category to which the entry or feed belongs.",
+                                                             "",
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_SCHEME,
+                                        g_param_spec_string ("scheme",
+                                                             "Scheme",
+                                                             "An IRI that identifies a categorization scheme.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       g_object_class_install_property (object_class, PROP_LABEL,
+                                        g_param_spec_string ("label",
+                                                             "Label",
+                                                             "A human-readable label for display in end-user applications.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+atom_category_init (AtomCategory *atom_category)
+{
+}
+
+/**
+ * atom_category_new:
+ * @term: a string that identifies the category to which the entry or feed belongs.
+ *
+ * Returns: the newly created #AtomCategory object.
+ */
+AtomCategory
+*atom_category_new (const gchar *term)
+{
+       AtomCategory *atom_category = ATOM_CATEGORY (g_object_new (atom_category_get_type (), NULL));
+
+       g_object_set (G_OBJECT (atom_category),
+                     "term", term,
+                     NULL);
+
+       return atom_category;
+}
+
+/**
+ * atom_category_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ * Returns: the newly created #AtomCategory object.
+ */
+AtomCategory
+*atom_category_new_from_xml (xmlNode *xnode)
+{
+       AtomCategory *atom_category = NULL;
+
+       gchar *term = (gchar *)xmlGetProp (xnode, (const xmlChar *)"term");
+       if (term == NULL || strcmp (g_strstrip (term), "") == 0)
+               {
+                       g_critical ("AtomCategory must have a term attribute.");
+                       return NULL;
+               }
+       else
+               {
+                       atom_category = atom_category_new (term);
+                       if (atom_category != NULL)
+                               {
+                                       atom_common_set_properties_from_xml (ATOM_COMMON (atom_category), xnode);
+
+                                       term = (gchar *)xmlGetProp (xnode, (const xmlChar *)"scheme");
+                                       if (term != NULL && strcmp (g_strstrip (term), "") != 0)
+                                               {
+                                                       g_object_set (G_OBJECT (atom_category),
+                                                                     "scheme", term,
+                                                                     NULL);
+                                               }
+
+                                       term = (gchar *)xmlGetProp (xnode, (const xmlChar *)"label");
+                                       if (term != NULL && strcmp (g_strstrip (term), "") != 0)
+                                               {
+                                                       g_object_set (G_OBJECT (atom_category),
+                                                                     "label", term,
+                                                                     NULL);
+                                               }
+                               }
+               }
+
+       return atom_category;
+}
+
+/**
+ * atom_category_get_xml:
+ * @atom_category: an #AtomCategory object.
+ * @xnode: an #xmlNode.
+ *
+ */
+void
+atom_category_get_xml (AtomCategory *atom_category, xmlNode *xnode)
+{
+       AtomCategoryPrivate *priv = ATOM_CATEGORY_GET_PRIVATE (atom_category);
+
+       atom_common_get_xml (ATOM_COMMON (atom_category), xnode);
+
+       xmlSetProp (xnode, (const xmlChar *)"term", (const xmlChar *)priv->term);
+
+       if (strcmp (priv->scheme, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"scheme", (const xmlChar *)priv->scheme);
+               }
+       if (strcmp (priv->label, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"label", (const xmlChar *)priv->label);
+               }
+}
+
+static void
+atom_category_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       AtomCategory *atom_category = ATOM_CATEGORY (object);
+
+       AtomCategoryPrivate *priv = ATOM_CATEGORY_GET_PRIVATE (atom_category);
+
+       switch (property_id)
+               {
+                       case PROP_TERM:
+                               {
+                                       gchar *term = g_strstrip (g_value_dup_string (value));
+                                       if (strcmp (term, "") == 0)
+                                               {
+                                                       g_warning ("Property term must not be empty.");
+                                               }
+                                       else
+                                               {
+                                                       priv->term = term;
+                                               }
+                                       break;
+                               }
+
+                       case PROP_SCHEME:
+                               priv->scheme = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       case PROP_LABEL:
+                               priv->label = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_category_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       AtomCategory *atom_category = ATOM_CATEGORY (object);
+
+       AtomCategoryPrivate *priv = ATOM_CATEGORY_GET_PRIVATE (atom_category);
+
+       switch (property_id)
+               {
+                       case PROP_TERM:
+                               g_value_set_string (value, priv->term);
+                               break;
+
+                       case PROP_SCHEME:
+                               g_value_set_string (value, priv->scheme);
+                               break;
+
+                       case PROP_LABEL:
+                               g_value_set_string (value, priv->label);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/atomcategory.h b/src/atomcategory.h
new file mode 100644 (file)
index 0000000..630f3db
--- /dev/null
@@ -0,0 +1,64 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_CATEGORY_H__
+#define __ATOM_CATEGORY_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "atomcommon.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM_CATEGORY                 (atom_category_get_type ())
+#define ATOM_CATEGORY(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM_CATEGORY, AtomCategory))
+#define ATOM_CATEGORY_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM_CATEGORY, AtomCategoryClass))
+#define IS_ATOM_CATEGORY(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM_CATEGORY))
+#define IS_ATOM_CATEGORY_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM_CATEGORY))
+#define ATOM_CATEGORY_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM_CATEGORY, AtomCategoryClass))
+
+
+typedef struct _AtomCategory AtomCategory;
+typedef struct _AtomCategoryClass AtomCategoryClass;
+
+struct _AtomCategory
+       {
+               AtomCommon parent;
+       };
+
+struct _AtomCategoryClass
+       {
+               AtomCommonClass parent_class;
+       };
+
+GType atom_category_get_type (void) G_GNUC_CONST;
+
+AtomCategory *atom_category_new (const gchar *term);
+AtomCategory *atom_category_new_from_xml (xmlNode *xnode);
+
+void atom_category_get_xml (AtomCategory *atom_category, xmlNode *xnode);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_CATEGORY_H__ */
diff --git a/src/atomcommon.c b/src/atomcommon.c
new file mode 100644 (file)
index 0000000..8368a88
--- /dev/null
@@ -0,0 +1,226 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include "atomcommon.h"
+
+enum
+{
+       PROP_0,
+       PROP_BASE,
+       PROP_LANG
+};
+
+static void atom_common_class_init (AtomCommonClass *klass);
+static void atom_common_init (AtomCommon *atom_common);
+
+static void atom_common_set_property (GObject *object,
+                                      guint property_id,
+                                      const GValue *value,
+                                      GParamSpec *pspec);
+static void atom_common_get_property (GObject *object,
+                                      guint property_id,
+                                      GValue *value,
+                                      GParamSpec *pspec);
+
+#define ATOM_COMMON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM_COMMON, AtomCommonPrivate))
+
+typedef struct _AtomCommonPrivate AtomCommonPrivate;
+struct _AtomCommonPrivate
+       {
+               gchar *base,
+                     *lang;
+       };
+
+GType
+atom_common_get_type (void)
+{
+       static GType atom_common_type = 0;
+
+       if (!atom_common_type)
+               {
+                       static const GTypeInfo atom_common_info =
+                       {
+                               sizeof (AtomCommonClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_common_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (AtomCommon),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_common_init,
+                               NULL
+                       };
+
+                       atom_common_type = g_type_register_static (G_TYPE_OBJECT, "AtomCommon",
+                                                                  &atom_common_info, 0);
+               }
+
+       return atom_common_type;
+}
+
+static void
+atom_common_class_init (AtomCommonClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomCommonPrivate));
+
+       object_class->set_property = atom_common_set_property;
+       object_class->get_property = atom_common_get_property;
+
+       g_object_class_install_property (object_class, PROP_BASE,
+                                        g_param_spec_string ("base",
+                                                             "Base",
+                                                             "Base",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       g_object_class_install_property (object_class, PROP_LANG,
+                                        g_param_spec_string ("lang",
+                                                             "Lang",
+                                                             "Lang",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+atom_common_init (AtomCommon *atom_common)
+{
+}
+
+/**
+ * atom_common_new:
+ *
+ * Returns: the newly created #AtomCommon object.
+ */
+AtomCommon
+*atom_common_new ()
+{
+       return ATOM_COMMON (g_object_new (atom_common_get_type (), NULL));
+}
+
+/**
+ * atom_common_set_properties_from_xml:
+ * @atom_common: an #AtomCommon object.
+ * #xnode: the #xmlNode from which to get properties.
+ *
+ */
+void
+atom_common_set_properties_from_xml (AtomCommon *atom_common, xmlNode *xnode)
+{
+       g_object_set (G_OBJECT (atom_common),
+                     "base", xmlGetProp (xnode, (const xmlChar *)"base"),
+                     "lang", xmlGetProp (xnode, (const xmlChar *)"lang"),
+                     NULL);
+}
+
+/**
+ * atom_common_get_xml:
+ * @atom_common: an #AtomCommon object.
+ * @xnode: the #xmlNode to fill.
+ *
+ */
+void
+atom_common_get_xml (AtomCommon *atom_common, xmlNode *xnode)
+{
+       AtomCommonPrivate *priv = ATOM_COMMON_GET_PRIVATE (atom_common);
+
+       xmlChar *prop = (xmlChar *)g_strstrip (priv->base);
+       if (!xmlStrEqual (prop, (const xmlChar *)""))
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"xml:base", prop);
+               }
+
+       prop = (xmlChar *)g_strstrip (priv->lang);
+       if (!xmlStrEqual (prop, (const xmlChar *)""))
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"xml:lang", prop);
+               }
+}
+
+static void
+atom_common_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       AtomCommon *atom_common = ATOM_COMMON (object);
+
+       AtomCommonPrivate *priv = ATOM_COMMON_GET_PRIVATE (atom_common);
+
+       switch (property_id)
+               {
+                       case PROP_BASE:
+                               if (value != NULL)
+                                       {
+                                               gchar *str = g_value_dup_string (value);
+                                               if (str == NULL)
+                                                       {
+                                                               priv->base = g_strdup ("");
+                                                       }
+                                               else
+                                                       {
+                                                               priv->base = g_strstrip (str);
+                                                       }
+                                       }
+                               break;
+
+                       case PROP_LANG:
+                               if (value != NULL)
+                                       {
+                                               gchar *str = g_value_dup_string (value);
+                                               if (str == NULL)
+                                                       {
+                                                               priv->lang = g_strdup ("");
+                                                       }
+                                               else
+                                                       {
+                                                               priv->lang = g_strstrip (str);
+                                                       }
+                                       }
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_common_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       AtomCommon *atom_common = ATOM_COMMON (object);
+
+       AtomCommonPrivate *priv = ATOM_COMMON_GET_PRIVATE (atom_common);
+
+       switch (property_id)
+               {
+                       case PROP_BASE:
+                               g_value_set_string (value, priv->base);
+                               break;
+
+                       case PROP_LANG:
+                               g_value_set_string (value, priv->lang);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/atomcommon.h b/src/atomcommon.h
new file mode 100644 (file)
index 0000000..b5e7cd3
--- /dev/null
@@ -0,0 +1,64 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_COMMON_H__
+#define __ATOM_COMMON_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM_COMMON                 (atom_common_get_type ())
+#define ATOM_COMMON(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM_COMMON, AtomCommon))
+#define ATOM_COMMON_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM_COMMON, AtomCommonClass))
+#define IS_ATOM_COMMON(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM_COMMON))
+#define IS_ATOM_COMMON_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM_COMMON))
+#define ATOM_COMMON_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM_COMMON, AtomCommonClass))
+
+
+typedef struct _AtomCommon AtomCommon;
+typedef struct _AtomCommonClass AtomCommonClass;
+
+struct _AtomCommon
+       {
+               GObject parent;
+       };
+
+struct _AtomCommonClass
+       {
+               GObjectClass parent_class;
+       };
+
+GType atom_common_get_type (void) G_GNUC_CONST;
+
+AtomCommon *atom_common_new (void);
+
+void atom_common_set_properties_from_xml (AtomCommon *atom_common, xmlNode *xnode);
+
+void atom_common_get_xml (AtomCommon *atom_common, xmlNode *xnode);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_COMMON_H__ */
diff --git a/src/atomcontent.c b/src/atomcontent.c
new file mode 100644 (file)
index 0000000..deaa20a
--- /dev/null
@@ -0,0 +1,344 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <libxml/xpath.h>
+
+#include "atomcontent.h"
+
+enum
+{
+       PROP_0,
+       PROP_TYPE,
+       PROP_MEDIA_TYPE,
+       PROP_SRC,
+       PROP_TEXT
+};
+
+static void atom_content_class_init (AtomContentClass *klass);
+static void atom_content_init (AtomContent *atom_content);
+
+static void atom_content_set_property (GObject *object,
+                                    guint property_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec);
+static void atom_content_get_property (GObject *object,
+                                    guint property_id,
+                                    GValue *value,
+                                    GParamSpec *pspec);
+
+#define ATOM_CONTENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM_CONTENT, AtomContentPrivate))
+
+typedef struct _AtomContentPrivate AtomContentPrivate;
+struct _AtomContentPrivate
+       {
+               AtomContentType type;
+               gchar *media_type,
+                     *src,
+                     *text;
+       };
+
+GType
+atom_content_get_type (void)
+{
+       static GType atom_content_type = 0;
+
+       if (!atom_content_type)
+               {
+                       static const GTypeInfo atom_content_info =
+                       {
+                               sizeof (AtomContentClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_content_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (AtomContent),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_content_init,
+                               NULL
+                       };
+
+                       atom_content_type = g_type_register_static (TYPE_ATOM_COMMON, "AtomContent",
+                                                                &atom_content_info, 0);
+               }
+
+       return atom_content_type;
+}
+
+static void
+atom_content_class_init (AtomContentClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomContentPrivate));
+
+       object_class->set_property = atom_content_set_property;
+       object_class->get_property = atom_content_get_property;
+
+       g_object_class_install_property (object_class, PROP_TYPE,
+                                        g_param_spec_uint ("type",
+                                                           "Type",
+                                                           "Type",
+                                                           0, 2, 0,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       g_object_class_install_property (object_class, PROP_MEDIA_TYPE,
+                                        g_param_spec_string ("media-type",
+                                                             "Media Type",
+                                                             "Media Type",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       g_object_class_install_property (object_class, PROP_SRC,
+                                        g_param_spec_string ("src",
+                                                             "Src",
+                                                             "Src",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       g_object_class_install_property (object_class, PROP_TEXT,
+                                        g_param_spec_string ("text",
+                                                             "Text",
+                                                             "Text",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+atom_content_init (AtomContent *atom_content)
+{
+}
+
+/**
+ * atom_content_new:
+ *
+ * Returns: the newly created #AtomContent object.
+ */
+AtomContent
+*atom_content_new (AtomContentType type)
+{
+       AtomContent *atomtext = ATOM_CONTENT (g_object_new (atom_content_get_type (), NULL));
+
+       g_object_set (G_OBJECT (atomtext),
+                     "type", type,
+                     NULL);
+
+       return atomtext;
+}
+
+/**
+ * atom_content_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ * Returns: the newly created #AtomContent object.
+ */
+AtomContent
+*atom_content_new_from_xml (xmlNode *xnode)
+{
+       AtomContent *atom_content = NULL;
+       AtomContentType atomtype;
+       gchar *text;
+
+       gchar *type = g_strstrip ((gchar *)xmlGetProp ((xmlNodePtr)xnode, (const xmlChar *)"type"));
+       if (type == NULL || strcmp (type, "") == 0 || strcmp (type, "text") == 0)
+               {
+                       atomtype = ATOM_CONTENT_TEXT;
+               }
+       else if (strcmp (type, "html") == 0)
+               {
+                       atomtype = ATOM_CONTENT_HTML;
+               }
+       else if (strcmp (type, "xhtml") == 0)
+               {
+                       atomtype = ATOM_CONTENT_XHTML;
+               }
+       else
+               {
+                       atomtype = ATOM_CONTENT_MEDIA;
+               }
+
+       if (atomtype == ATOM_CONTENT_TEXT || atomtype == ATOM_CONTENT_HTML || atomtype == ATOM_CONTENT_MEDIA)
+               {
+                       text = (gchar *)xmlNodeGetContent ((xmlNodePtr)xnode);
+               }
+       else if (atomtype == ATOM_CONTENT_XHTML)
+               {
+                       xmlXPathObjectPtr xpresult;
+                       xmlXPathContextPtr xpcontext = xmlXPathNewContext (xnode->doc);
+
+                       xmlXPathRegisterNs (xpcontext, (const xmlChar *)"xhtml", (const xmlChar *)"http://www.w3.org/1999/xhtml");
+
+                       xpcontext->node = xnode;
+                       xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::xhtml:div", xpcontext);
+                       if (xpresult == NULL || xpresult->nodesetval == NULL || xpresult->nodesetval->nodeNr != 1)
+                               {
+                                       g_critical ("Invalid AtomContent type xhtml.");
+                                       return NULL;
+                               }
+                       else
+                               {
+                                       text = (gchar *)xmlNodeGetContent ((xmlNodePtr)xpresult->nodesetval->nodeTab[0]);
+                               }
+               }
+
+       atom_content = atom_content_new (atomtype);
+
+       if (atomtype == ATOM_CONTENT_MEDIA)
+               {
+                       gchar *src = (gchar *)xmlGetProp (xnode, (const xmlChar *)"src");
+                       if (src != NULL)
+                               {
+                                       text = NULL;
+                                       g_object_set (G_OBJECT (atom_content),
+                                                     "src", src,
+                                                     NULL);
+                               }
+               }
+
+       if (atom_content != NULL)
+               {
+                       atom_common_set_properties_from_xml (ATOM_COMMON (atom_content), xnode);
+
+                       if (text != NULL)
+                               {
+                                       g_object_set (G_OBJECT (atom_content),
+                                                     "text", text,
+                                                     NULL);
+                               }
+               }
+
+       return atom_content;
+}
+
+/**
+ * atom_content_get_xml:
+ * @atom_content: an #AtomContent object.
+ * @xnode: an #xmlNode.
+ *
+ */
+void
+atom_content_get_xml (AtomContent *atom_content, xmlNode *xnode)
+{
+       gchar *type;
+
+       AtomContentPrivate *priv = ATOM_CONTENT_GET_PRIVATE (atom_content);
+
+       atom_common_get_xml (ATOM_COMMON (atom_content), xnode);
+
+       switch (priv->type)
+               {
+                       case ATOM_CONTENT_TEXT:
+                               type = g_strdup ("text");
+                               break;
+
+                       case ATOM_CONTENT_HTML:
+                               type = g_strdup ("html");
+                               break;
+
+                       case ATOM_CONTENT_XHTML:
+                               type = g_strdup ("xhtml");
+                               break;
+
+                       case ATOM_CONTENT_MEDIA:
+                               type = g_strdup (priv->media_type);
+                               break;
+               }
+
+       xmlSetProp (xnode, (const xmlChar *)"type", (const xmlChar *)type);
+
+       if (priv->type == ATOM_CONTENT_MEDIA && strcmp (priv->src, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"src", (const xmlChar *)priv->src);
+               }
+       else if (priv->type == ATOM_CONTENT_XHTML)
+               {
+                       xmlNode *new_xnode = xmlNewNode (NULL, (const xmlChar *)"xhtml:div");
+                       xmlNewNs (new_xnode, (const xmlChar *)"http://www.w3.org/1999/xhtml", (const xmlChar *)"xhtml");
+                       xmlNodeSetContent (new_xnode, (const xmlChar *)priv->text);
+                       xmlAddChild (xnode, new_xnode);
+               }
+       else
+               {
+                       xmlNodeSetContent (xnode, (const xmlChar *)priv->text);
+               }
+}
+
+static void
+atom_content_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       AtomContent *atom_content = ATOM_CONTENT (object);
+
+       AtomContentPrivate *priv = ATOM_CONTENT_GET_PRIVATE (atom_content);
+
+       switch (property_id)
+               {
+                       case PROP_TYPE:
+                               priv->type = g_value_get_uint (value);
+                               break;
+
+                       case PROP_MEDIA_TYPE:
+                               priv->media_type = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       case PROP_SRC:
+                               priv->src = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       case PROP_TEXT:
+                               priv->text = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_content_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       AtomContent *atom_content = ATOM_CONTENT (object);
+
+       AtomContentPrivate *priv = ATOM_CONTENT_GET_PRIVATE (atom_content);
+
+       switch (property_id)
+               {
+                       case PROP_TYPE:
+                               g_value_set_int (value, priv->type);
+                               break;
+
+                       case PROP_MEDIA_TYPE:
+                               g_value_set_string (value, priv->media_type);
+                               break;
+
+                       case PROP_SRC:
+                               g_value_set_string (value, priv->src);
+                               break;
+
+                       case PROP_TEXT:
+                               g_value_set_string (value, priv->text);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/atomcontent.h b/src/atomcontent.h
new file mode 100644 (file)
index 0000000..df160e2
--- /dev/null
@@ -0,0 +1,72 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_CONTENT_H__
+#define __ATOM_CONTENT_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "atomcommon.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM_CONTENT                 (atom_content_get_type ())
+#define ATOM_CONTENT(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM_CONTENT, AtomContent))
+#define ATOM_CONTENT_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM_CONTENT, AtomContentClass))
+#define IS_ATOM_CONTENT(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM_CONTENT))
+#define IS_ATOM_CONTENT_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM_CONTENT))
+#define ATOM_CONTENT_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM_CONTENT, AtomContentClass))
+
+
+typedef struct _AtomContent AtomContent;
+typedef struct _AtomContentClass AtomContentClass;
+
+struct _AtomContent
+       {
+               AtomCommon parent;
+       };
+
+struct _AtomContentClass
+       {
+               AtomCommonClass parent_class;
+       };
+
+typedef enum
+{
+       ATOM_CONTENT_TEXT,
+       ATOM_CONTENT_HTML,
+       ATOM_CONTENT_XHTML,
+       ATOM_CONTENT_MEDIA
+} AtomContentType;
+
+GType atom_content_get_type (void) G_GNUC_CONST;
+
+AtomContent *atom_content_new (AtomContentType type);
+AtomContent *atom_content_new_from_xml (xmlNode *xnode);
+
+void atom_content_get_xml (AtomContent *atom_content, xmlNode *xnode);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_CONTENT_H__ */
diff --git a/src/atomdate.c b/src/atomdate.c
new file mode 100644 (file)
index 0000000..ec82b15
--- /dev/null
@@ -0,0 +1,217 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include "atomdate.h"
+
+enum
+{
+       PROP_0,
+       PROP_DATE
+};
+
+static void atom_date_class_init (AtomDateClass *klass);
+static void atom_date_init (AtomDate *atom_date);
+
+static void atom_date_set_property (GObject *object,
+                                    guint property_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec);
+static void atom_date_get_property (GObject *object,
+                                    guint property_id,
+                                    GValue *value,
+                                    GParamSpec *pspec);
+
+#define ATOM_DATE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM_DATE, AtomDatePrivate))
+
+typedef struct _AtomDatePrivate AtomDatePrivate;
+struct _AtomDatePrivate
+       {
+               struct tm *dateTime;
+       };
+
+GType
+atom_date_get_type (void)
+{
+       static GType atom_date_type = 0;
+
+       if (!atom_date_type)
+               {
+                       static const GTypeInfo atom_date_info =
+                       {
+                               sizeof (AtomDateClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_date_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (AtomDate),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_date_init,
+                               NULL
+                       };
+
+                       atom_date_type = g_type_register_static (TYPE_ATOM_COMMON, "AtomDate",
+                                                                &atom_date_info, 0);
+               }
+
+       return atom_date_type;
+}
+
+static void
+atom_date_class_init (AtomDateClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomDatePrivate));
+
+       object_class->set_property = atom_date_set_property;
+       object_class->get_property = atom_date_get_property;
+
+       g_object_class_install_property (object_class, PROP_DATE,
+                                        g_param_spec_pointer ("date",
+                                                              "Date",
+                                                              "Date",
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+atom_date_init (AtomDate *atom_date)
+{
+}
+
+/**
+ * atom_date_new:
+ * @dateTime: a tm struct.
+ *
+ * Returns: the newly created #AtomDate object.
+ */
+AtomDate
+*atom_date_new (struct tm dateTime)
+{
+       AtomDate *atomdate = ATOM_DATE (g_object_new (atom_date_get_type (), NULL));
+
+       g_object_set (G_OBJECT (atomdate),
+                     "date", &dateTime,
+                     NULL);
+
+       return atomdate;
+}
+
+/**
+ * atom_date_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ * Returns: the newly created #AtomDate object.
+ */
+AtomDate
+*atom_date_new_from_xml (xmlNode *xnode)
+{
+       AtomDate *atom_date = NULL;
+
+       gchar *date = (gchar *)xmlNodeGetContent ((xmlNodePtr)xnode);
+       if (date == NULL)
+               {
+                       g_critical ("Invalid date content.");
+               }
+       else
+               {
+                       struct tm dateTime;
+
+                       gchar *ret = (gchar *)strptime (g_strstrip (date), "%Y-%m-%dT%H:%M:%SZ", &dateTime);
+                       if (ret != NULL)
+                               {
+                                       atom_date = atom_date_new (dateTime);
+                                       if (atom_date != NULL)
+                                               {
+                                                       atom_common_set_properties_from_xml (ATOM_COMMON (atom_date), xnode);
+                                               }
+                               }
+               }
+
+       return atom_date;
+}
+
+/**
+ * atom_date_get_xml:
+ * @atom_date: an #AtomDate object.
+ * @xnode: the #xmlNode to fill.
+ *
+ */
+void
+atom_date_get_xml (AtomDate *atom_date, xmlNode *xnode)
+{
+       gchar *buf;
+
+       AtomDatePrivate *priv = ATOM_DATE_GET_PRIVATE (atom_date);
+
+       atom_common_get_xml (ATOM_COMMON (atom_date), xnode);
+
+       buf = g_strdup_printf ("%04d-%02d-%02dT%02d:%02d:%02dZ",
+                              priv->dateTime->tm_year + 1900,
+                              priv->dateTime->tm_mon + 1,
+                              priv->dateTime->tm_mday,
+                              priv->dateTime->tm_hour,
+                              priv->dateTime->tm_min,
+                              priv->dateTime->tm_sec);
+
+       xmlNodeSetContent (xnode, (const xmlChar *)buf);
+}
+
+static void
+atom_date_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       AtomDate *atom_date = ATOM_DATE (object);
+
+       AtomDatePrivate *priv = ATOM_DATE_GET_PRIVATE (atom_date);
+
+       switch (property_id)
+               {
+                       case PROP_DATE:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->dateTime = (struct tm *)g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (struct tm));
+                                       }
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_date_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       AtomDate *atom_date = ATOM_DATE (object);
+
+       AtomDatePrivate *priv = ATOM_DATE_GET_PRIVATE (atom_date);
+
+       switch (property_id)
+               {
+                       case PROP_DATE:
+                               g_value_set_pointer (value, priv->dateTime);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/atomdate.h b/src/atomdate.h
new file mode 100644 (file)
index 0000000..ab13d9b
--- /dev/null
@@ -0,0 +1,66 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_DATE_H__
+#define __ATOM_DATE_H__
+
+#include <time.h>
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "atomcommon.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM_DATE                 (atom_date_get_type ())
+#define ATOM_DATE(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM_DATE, AtomDate))
+#define ATOM_DATE_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM_DATE, AtomDateClass))
+#define IS_ATOM_DATE(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM_DATE))
+#define IS_ATOM_DATE_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM_DATE))
+#define ATOM_DATE_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM_DATE, AtomDateClass))
+
+
+typedef struct _AtomDate AtomDate;
+typedef struct _AtomDateClass AtomDateClass;
+
+struct _AtomDate
+       {
+               AtomCommon parent;
+       };
+
+struct _AtomDateClass
+       {
+               AtomCommonClass parent_class;
+       };
+
+GType atom_date_get_type (void) G_GNUC_CONST;
+
+AtomDate *atom_date_new (struct tm dateTime);
+AtomDate *atom_date_new_from_xml (xmlNode *xnode);
+
+void atom_date_get_xml (AtomDate *atom_date, xmlNode *xnode);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_DATE_H__ */
diff --git a/src/atomentry.c b/src/atomentry.c
new file mode 100644 (file)
index 0000000..19d67b5
--- /dev/null
@@ -0,0 +1,680 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <libxml/xpath.h>
+
+#include "atomentry.h"
+#include "atomperson.h"
+#include "atomcategory.h"
+#include "atomcontent.h"
+#include "atomlink.h"
+#include "atomsource.h"
+
+enum
+{
+       PROP_0,
+       PROP_AUTHOR,
+       PROP_CATEGORY,
+       PROP_CONTENT,
+       PROP_CONTRIBUTOR,
+       PROP_ID,
+       PROP_LINK,
+       PROP_PUBLISHED,
+       PROP_RIGHTS,
+       PROP_SOURCE,
+       PROP_SUMMARY,
+       PROP_TITLE,
+       PROP_UPDATED
+};
+
+static void atom_entry_class_init (AtomEntryClass *klass);
+static void atom_entry_init (AtomEntry *atome);
+
+static void atom_entry_set_property (GObject *object,
+                                     guint property_id,
+                                     const GValue *value,
+                                     GParamSpec *pspec);
+static void atom_entry_get_property (GObject *object,
+                                     guint property_id,
+                                     GValue *value,
+                                     GParamSpec *pspec);
+
+#define ATOM_ENTRY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM_ENTRY, AtomEntryPrivate))
+
+typedef struct _AtomEntryPrivate AtomEntryPrivate;
+struct _AtomEntryPrivate
+       {
+               GList *author,
+                     *category,
+                     *contributor;
+               AtomContent *content;
+               AtomID *id;
+               AtomLink *link;
+               AtomText *title,
+                        *rights,
+                        *summary;
+               AtomDate *published,
+                        *updated;
+               AtomSource *source;
+       };
+
+GType
+atom_entry_get_type (void)
+{
+       static GType atom_entry_type = 0;
+
+       if (!atom_entry_type)
+               {
+                       static const GTypeInfo atom_entry_info =
+                       {
+                               sizeof (AtomEntryClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_entry_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (AtomEntry),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_entry_init,
+                               NULL
+                       };
+
+                       atom_entry_type = g_type_register_static (TYPE_ATOM_COMMON, "AtomEntry",
+                                                                 &atom_entry_info, 0);
+               }
+
+       return atom_entry_type;
+}
+
+static void
+atom_entry_class_init (AtomEntryClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomEntryPrivate));
+
+       object_class->set_property = atom_entry_set_property;
+       object_class->get_property = atom_entry_get_property;
+
+       g_object_class_install_property (object_class, PROP_AUTHOR,
+                                        g_param_spec_pointer ("author",
+                                                              "Author",
+                                                              "An #AtomPerson object that indicates the author of the entry.",
+                                                              G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_CATEGORY,
+                                        g_param_spec_pointer ("category",
+                                                              "Category",
+                                                              "Information about a category associated with an entry.",
+                                                              G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_CONTENT,
+                                        g_param_spec_object ("content",
+                                                             "Content",
+                                                             "Either contains or links to the content of the entry.",
+                                                             TYPE_ATOM_CONTENT,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_CONTRIBUTOR,
+                                        g_param_spec_pointer ("contributor",
+                                                              "Contributor",
+                                                              "Indicates a person or other entity who contributed to the entry or feed.",
+                                                              G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_ID,
+                                        g_param_spec_object ("id",
+                                                             "Id",
+                                                             "A permanent, universally unique identifier for an entry.",
+                                                             TYPE_ATOM_ID,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_LINK,
+                                        g_param_spec_object ("link",
+                                                             "Link",
+                                                             "An #AtomLink defines a reference from an entry or feed to a Web resource.",
+                                                             TYPE_ATOM_LINK,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_PUBLISHED,
+                                        g_param_spec_object ("published",
+                                                             "Published",
+                                                             "An #AtomDate object indicating an instant in time associated with an event early in the life cycle of the entry.",
+                                                             TYPE_ATOM_DATE,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_RIGHTS,
+                                        g_param_spec_object ("rights",
+                                                             "Rights",
+                                                             "Conveys information about rights held in and over an entry.",
+                                                             TYPE_ATOM_TEXT,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_SOURCE,
+                                        g_param_spec_object ("source",
+                                                             "Source",
+                                                             "Source",
+                                                             TYPE_ATOM_SOURCE,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_SUMMARY,
+                                        g_param_spec_object ("summary",
+                                                             "Summary",
+                                                             "Conveys a short summary, abstract, or excerpt of an entry.",
+                                                             TYPE_ATOM_TEXT,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_TITLE,
+                                        g_param_spec_object ("title",
+                                                             "Title",
+                                                             "A human-readable title for the entry.",
+                                                             TYPE_ATOM_TEXT,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_UPDATED,
+                                        g_param_spec_object ("updated",
+                                                             "Updated",
+                                                             "The most recent instant in time when the entry was modified in a way the publisher considers significant.",
+                                                             TYPE_ATOM_DATE,
+                                                             G_PARAM_READWRITE));
+}
+
+static void
+atom_entry_init (AtomEntry *atome)
+{
+}
+
+/**
+ * atom_entry_new:
+ * @id: a permanent, universally unique identifier for an entry or feed.
+ * @title: a human-readable title for an entry or feed.
+ * @updated: the most recent instant in time when an entry or feed was modified in a way the publisher considers significant.
+ *
+ * Returns: the newly created #AtomEntry object.
+ */
+AtomEntry
+*atom_entry_new (AtomID *id, AtomText *title, AtomDate *updated)
+{
+       AtomEntry *atom_entry = ATOM_ENTRY (g_object_new (atom_entry_get_type (), NULL));
+
+       g_object_set (G_OBJECT (atom_entry),
+                     "id", id,
+                     "title", title,
+                     "updated", updated,
+                     NULL);
+
+       return atom_entry;
+}
+
+/**
+ * atom_entry_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ * Returns: the newly created #AtomEntry object.
+ */
+AtomEntry
+*atom_entry_new_from_xml (xmlNode *xnode)
+{
+       AtomEntry *atom_entry = NULL;
+
+       AtomID *id = NULL;
+       AtomText *title = NULL;
+       AtomDate *updated = NULL;
+                                                                               
+       xmlXPathObjectPtr xpresult;
+       xmlXPathContextPtr xpcontext = xmlXPathNewContext (xnode->doc);
+
+       xmlXPathRegisterNs (xpcontext, (const xmlChar *)"atom", (const xmlChar *)"http://www.w3.org/2005/Atom");
+
+       /* searching for id */
+       xpcontext->node = xnode;
+       xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::atom:id", xpcontext);
+       if (xpresult == NULL || xpresult->nodesetval == NULL || xpresult->nodesetval->nodeNr != 1)
+               {
+                       g_critical ("Atom entry must contain one and only id element.");
+               }
+       else
+               {
+                       id = atom_id_new_from_xml (xpresult->nodesetval->nodeTab[0]);
+                       if (id == NULL)
+                               {
+                                       g_critical ("Invalid id element.");
+                               }
+               }
+
+       /* searching for title */
+       xpcontext->node = xnode;
+       xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::atom:title", xpcontext);
+       if (xpresult == NULL || xpresult->nodesetval == NULL || xpresult->nodesetval->nodeNr != 1)
+               {
+                       g_critical ("Atom entry must contain one and only title element.");
+               }
+       else
+               {
+                       title = atom_text_new_from_xml (xpresult->nodesetval->nodeTab[0]);
+                       if (title == NULL)
+                               {
+                                       g_critical ("Invalid title element.");
+                               }
+               }
+
+       /* searching for updated */
+       xpcontext->node = xnode;
+       xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::atom:updated", xpcontext);
+       if (xpresult == NULL || xpresult->nodesetval == NULL || xpresult->nodesetval->nodeNr != 1)
+               {
+                       g_critical ("Atom entry must contain one and only updated element.");
+               }
+       else
+               {
+                       updated = atom_date_new_from_xml (xpresult->nodesetval->nodeTab[0]);
+                       if (updated == NULL)
+                               {
+                                       g_critical ("Invalid updated element.");
+                               }
+               }
+
+       if (id != NULL && title != NULL && updated != NULL)
+               {
+                       atom_entry = atom_entry_new (id, title, updated);
+
+                       AtomEntryPrivate *priv = ATOM_ENTRY_GET_PRIVATE (atom_entry);
+
+                       atom_common_set_properties_from_xml (ATOM_COMMON (atom_entry), xnode);
+
+                       xmlNode *cur = xnode->children;
+
+                       while (cur != NULL)
+                               {
+                                       if (xmlStrcmp (cur->name, (const xmlChar *)"author") == 0)
+                                               {
+                                                       AtomPerson *ap = atom_person_new_from_xml (cur);
+                                                       if (ap != NULL)
+                                                               {
+                                                                       priv->author = g_list_append (priv->author, ap);
+                                                               }
+                                               }
+                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"category") == 0)
+                                               {
+                                                       AtomCategory *ac = atom_category_new_from_xml (cur);
+                                                       if (ac != NULL)
+                                                               {
+                                                                       priv->category = g_list_append (priv->category, ac);
+                                                               }
+                                               }
+                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"content") == 0)
+                                               {
+                                                       AtomContent *ac = atom_content_new_from_xml (cur);
+                                                       if (ac != NULL)
+                                                               {
+                                                                       priv->content = ac;
+                                                               }
+                                               }
+                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"contributor") == 0)
+                                               {
+                                                       AtomPerson *ap = atom_person_new_from_xml (cur);
+                                                       if (ap != NULL)
+                                                               {
+                                                                       priv->contributor = g_list_append (priv->contributor, ap);
+                                                               }
+                                               }
+                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"id") == 0)
+                                               {
+                                                       AtomID *id = atom_id_new_from_xml (cur);
+                                                       if (id == NULL)
+                                                               {
+                                                                       priv->id = id;
+                                                               }
+                                               }
+                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"link") == 0)
+                                               {
+                                                       AtomLink *link = atom_link_new_from_xml (cur);
+                                                       if (link == NULL)
+                                                               {
+                                                                       priv->link = link;
+                                                               }
+                                               }
+                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"published") == 0)
+                                               {
+                                                       AtomDate *published = atom_date_new_from_xml (cur);
+                                                       if (published != NULL)
+                                                               {
+                                                                       priv->published = published;
+                                                               }
+                                               }
+                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"rights") == 0)
+                                               {
+                                                       AtomText *rights = atom_text_new_from_xml (cur);
+                                                       if (rights != NULL)
+                                                               {
+                                                                       priv->rights = rights;
+                                                               }
+                                               }
+                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"source") == 0)
+                                               {
+                                                       AtomSource *source = atom_source_new_from_xml (cur);
+                                                       if (source != NULL)
+                                                               {
+                                                                       priv->source = source;
+                                                               }
+                                               }
+                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"summary") == 0)
+                                               {
+                                                       AtomText *summary = atom_text_new_from_xml (cur);
+                                                       if (summary != NULL)
+                                                               {
+                                                                       priv->summary = summary;
+                                                               }
+                                               }
+                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"title") == 0)
+                                               {
+                                                       AtomText *title = atom_text_new_from_xml (cur);
+                                                       if (title != NULL)
+                                                               {
+                                                                       priv->title = title;
+                                                               }
+                                               }
+                                       else if (xmlStrcmp (cur->name, (const xmlChar *)"updated") == 0)
+                                               {
+                                                       AtomDate *updated = atom_date_new_from_xml (cur);
+                                                       if (updated != NULL)
+                                                               {
+                                                                       priv->updated = updated;
+                                                               }
+                                               }
+
+                                       cur = cur->next;
+                               }
+               }
+
+       return atom_entry;
+}
+
+/**
+ * atatom_entry_get_xml:
+ * @atom_entry: an #AtomEntry object.
+ * @xnode: an #xmlNode.
+ *
+ */
+void
+atom_entry_get_xml (AtomEntry *atom_entry, xmlNode *xnode)
+{
+       xmlNode *xnodenew;
+       GList *lst;
+
+       AtomEntryPrivate *priv = ATOM_ENTRY_GET_PRIVATE (atom_entry);
+
+       atom_common_get_xml (ATOM_COMMON (atom_entry), xnode);
+
+       lst = g_list_first (priv->author);
+       while (lst != NULL)
+               {
+                       if (IS_ATOM_PERSON (lst->data))
+                               {
+                                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"author");
+                                       xmlAddChild (xnode, xnodenew);
+                                       atom_person_get_xml (ATOM_PERSON (lst->data), xnodenew);
+                               }
+
+                       lst = g_list_next (lst);
+               }
+
+       lst = g_list_first (priv->category);
+       while (lst != NULL)
+               {
+                       if (IS_ATOM_CATEGORY (lst->data))
+                               {
+                                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"category");
+                                       xmlAddChild (xnode, xnodenew);
+                                       atom_category_get_xml (ATOM_CATEGORY (lst->data), xnodenew);
+                               }
+
+                       lst = g_list_next (lst);
+               }
+
+       if (priv->content != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"content");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_content_get_xml (priv->content, xnodenew);
+               }
+
+       lst = g_list_first (priv->contributor);
+       while (lst != NULL)
+               {
+                       if (IS_ATOM_PERSON (lst->data))
+                               {
+                                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"contributor");
+                                       xmlAddChild (xnode, xnodenew);
+                                       atom_person_get_xml (ATOM_PERSON (lst->data), xnodenew);
+                               }
+
+                       lst = g_list_next (lst);
+               }
+
+       if (priv->id != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"id");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_id_get_xml (priv->id, xnodenew);
+               }
+
+       if (priv->link != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"link");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_link_get_xml (priv->link, xnodenew);
+               }
+
+       if (priv->published != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"published");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_date_get_xml (priv->published, xnodenew);
+               }
+
+       if (priv->rights != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"rights");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_text_get_xml (priv->rights, xnodenew);
+               }
+
+       if (priv->source != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"source");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_source_get_xml (priv->source, xnodenew);
+               }
+
+       if (priv->summary != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"summary");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_text_get_xml (priv->summary, xnodenew);
+               }
+
+       if (priv->title != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"title");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_text_get_xml (priv->title, xnodenew);
+               }
+
+       if (priv->updated != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"updated");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_date_get_xml (priv->updated, xnodenew);
+               }
+}
+
+static void
+atom_entry_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       GObject *obj;
+
+       AtomEntry *atome = ATOM_ENTRY (object);
+
+       AtomEntryPrivate *priv = ATOM_ENTRY_GET_PRIVATE (atome);
+
+       switch (property_id)
+               {
+                       case PROP_AUTHOR:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->author = (GList *)g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (GList));
+                                       }
+                               break;
+
+                       case PROP_CATEGORY:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->category = (GList *)g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (GList));
+                                       }
+                               break;
+
+                       case PROP_CONTENT:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_CONTENT (g_value_get_object (value)))
+                                       {
+                                               priv->content = (AtomContent *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_CONTRIBUTOR:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->contributor = (GList *)g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (GList));
+                                       }
+                               break;
+
+                       case PROP_ID:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_ID (g_value_get_object (value)))
+                                       {
+                                               priv->id = (AtomID *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_LINK:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_LINK (g_value_get_object (value)))
+                                       {
+                                               priv->link = (AtomLink *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_RIGHTS:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_TEXT (g_value_get_object (value)))
+                                       {
+                                               priv->rights = (AtomText *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_SOURCE:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_SOURCE (g_value_get_object (value)))
+                                       {
+                                               priv->source = (AtomSource *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_SUMMARY:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_TEXT (g_value_get_object (value)))
+                                       {
+                                               priv->summary = (AtomText *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_TITLE:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_TEXT (g_value_get_object (value)))
+                                       {
+                                               priv->title = (AtomText *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_UPDATED:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_DATE (g_value_get_object (value)))
+                                       {
+                                               priv->updated = (AtomDate *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_entry_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       AtomEntry *atome = ATOM_ENTRY (object);
+
+       AtomEntryPrivate *priv = ATOM_ENTRY_GET_PRIVATE (atome);
+       
+       switch (property_id)
+               {
+                       case PROP_AUTHOR:
+                               g_value_set_pointer (value, priv->author);
+                               break;
+
+                       case PROP_CATEGORY:
+                               g_value_set_pointer (value, priv->category);
+                               break;
+
+                       case PROP_CONTENT:
+                               g_value_set_object (value, priv->content);
+                               break;
+
+                       case PROP_CONTRIBUTOR:
+                               g_value_set_pointer (value, priv->contributor);
+                               break;
+
+                       case PROP_ID:
+                               g_value_set_object (value, priv->id);
+                               break;
+
+                       case PROP_LINK:
+                               g_value_set_object (value, priv->link);
+                               break;
+
+                       case PROP_SOURCE:
+                               g_value_set_object (value, priv->source);
+                               break;
+
+                       case PROP_RIGHTS:
+                               g_value_set_object (value, priv->rights);
+                               break;
+
+                       case PROP_SUMMARY:
+                               g_value_set_object (value, priv->summary);
+                               break;
+
+                       case PROP_TITLE:
+                               g_value_set_object (value, priv->title);
+                               break;
+
+                       case PROP_UPDATED:
+                               g_value_set_object (value, priv->updated);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/atomentry.h b/src/atomentry.h
new file mode 100644 (file)
index 0000000..90e0654
--- /dev/null
@@ -0,0 +1,68 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_ENTRY_H__
+#define __ATOM_ENTRY_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+#include "atomcommon.h"
+#include "atomid.h"
+#include "atomtext.h"
+#include "atomdate.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM_ENTRY                 (atom_entry_get_type ())
+#define ATOM_ENTRY(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM_ENTRY, AtomEntry))
+#define ATOM_ENTRY_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM_ENTRY, AtomEntryClass))
+#define IS_ATOM_ENTRY(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM_ENTRY))
+#define IS_ATOM_ENTRY_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM_ENTRY))
+#define ATOM_ENTRY_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM_ENTRY, AtomEntryClass))
+
+
+typedef struct _AtomEntry AtomEntry;
+typedef struct _AtomEntryClass AtomEntryClass;
+
+struct _AtomEntry
+       {
+               AtomCommon parent;
+       };
+
+struct _AtomEntryClass
+       {
+               AtomCommonClass parent_class;
+       };
+
+GType atom_entry_get_type (void) G_GNUC_CONST;
+
+AtomEntry *atom_entry_new (AtomID *id, AtomText *title, AtomDate *updated);
+AtomEntry *atom_entry_new_from_xml (xmlNode *xnode);
+
+void atom_entry_get_xml (AtomEntry *atom_entry, xmlNode *xnode);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_ENTRY_H__ */
diff --git a/src/atomgenerator.c b/src/atomgenerator.c
new file mode 100644 (file)
index 0000000..a8236b4
--- /dev/null
@@ -0,0 +1,271 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include "atomgenerator.h"
+
+enum
+{
+       PROP_0,
+       PROP_URI,
+       PROP_VERSION,
+       PROP_TEXT
+};
+
+static void atom_generator_class_init (AtomGeneratorClass *klass);
+static void atom_generator_init (AtomGenerator *atom_generator);
+
+static void atom_generator_set_property (GObject *object,
+                                    guint property_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec);
+static void atom_generator_get_property (GObject *object,
+                                    guint property_id,
+                                    GValue *value,
+                                    GParamSpec *pspec);
+
+#define ATOM_GENERATOR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM_GENERATOR, AtomGeneratorPrivate))
+
+typedef struct _AtomGeneratorPrivate AtomGeneratorPrivate;
+struct _AtomGeneratorPrivate
+       {
+               gchar *uri,
+                     *version,
+                     *text;
+       };
+
+GType
+atom_generator_get_type (void)
+{
+       static GType atom_generator_type = 0;
+
+       if (!atom_generator_type)
+               {
+                       static const GTypeInfo atom_generator_info =
+                       {
+                               sizeof (AtomGeneratorClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_generator_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (AtomGenerator),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_generator_init,
+                               NULL
+                       };
+
+                       atom_generator_type = g_type_register_static (TYPE_ATOM_COMMON, "AtomGenerator",
+                                                                     &atom_generator_info, 0);
+               }
+
+       return atom_generator_type;
+}
+
+static void
+atom_generator_class_init (AtomGeneratorClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomGeneratorPrivate));
+
+       object_class->set_property = atom_generator_set_property;
+       object_class->get_property = atom_generator_get_property;
+
+       g_object_class_install_property (object_class, PROP_URI,
+                                        g_param_spec_string ("uri",
+                                                             "URI",
+                                                             "URI",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       g_object_class_install_property (object_class, PROP_VERSION,
+                                        g_param_spec_string ("version",
+                                                             "Version",
+                                                             "The version of the generating agent.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       g_object_class_install_property (object_class, PROP_TEXT,
+                                        g_param_spec_string ("text",
+                                                             "Text",
+                                                             "A string that is a human-readable name for the generating agent.",
+                                                             "",
+                                                             G_PARAM_READWRITE));
+}
+
+static void
+atom_generator_init (AtomGenerator *atom_generator)
+{
+}
+
+/**
+ * atom_generator_new:
+ * @text: a string that is a human-readable name for the generating agent.
+ *
+ * Returns: the newly created #AtomGenerator object.
+ */
+AtomGenerator
+*atom_generator_new (const gchar *text)
+{
+       AtomGenerator *atom_generator = ATOM_GENERATOR (g_object_new (atom_generator_get_type (), NULL));
+
+       g_object_set (G_OBJECT (atom_generator),
+                     "text", text,
+                     NULL);
+
+       return atom_generator;
+}
+
+/**
+ * atom_generator_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ * Returns: the newly created #AtomGenerator object.
+ */
+AtomGenerator
+*atom_generator_new_from_xml (xmlNode *xnode)
+{
+       AtomGenerator *atom_generator = NULL;
+
+       gchar *text = (gchar *)xmlNodeGetContent (xnode);
+       if (text != NULL && strcmp (g_strstrip (text), "") == 0)
+               {
+                       g_critical ("AtomGenerator must have a text content.");
+                       return NULL;
+               }
+
+       atom_generator = atom_generator_new (text);
+       if (atom_generator != NULL)
+               {
+                       atom_common_set_properties_from_xml (ATOM_COMMON (atom_generator), xnode);
+               
+                       text = (gchar *)xmlGetProp (xnode, (const xmlChar *)"uri");
+                       if (text != NULL && strcmp (g_strstrip (text), "") != 0)
+                               {
+                                       g_object_set (G_OBJECT (atom_generator),
+                                                     "uri", text,
+                                                     NULL);
+                               }
+
+                       text = (gchar *)xmlGetProp (xnode, (const xmlChar *)"version");
+                       if (text != NULL && strcmp (g_strstrip (text), "") != 0)
+                               {
+                                       g_object_set (G_OBJECT (atom_generator),
+                                                     "version", text,
+                                                     NULL);
+                               }
+               }
+
+       return atom_generator;
+}
+
+/**
+ * atom_generator_get_xml:
+ * @atom_generator: an #AtomGenerator object.
+ * @xnode: an #xmlNode.
+ *
+ */
+void
+atom_generator_get_xml (AtomGenerator *atom_generator, xmlNode *xnode)
+{
+       xmlNode *new_xnode;
+
+       AtomGeneratorPrivate *priv = ATOM_GENERATOR_GET_PRIVATE (atom_generator);
+
+       atom_common_get_xml (ATOM_COMMON (atom_generator), xnode);
+
+       if (strcmp (priv->uri, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"uri", (const xmlChar *)priv->uri);
+               }
+       if (strcmp (priv->version, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"version", (const xmlChar *)priv->version);
+               }
+
+       new_xnode = xmlNewNode (NULL, (const xmlChar *)"text");
+       xmlNodeSetContent (new_xnode, (const xmlChar *)priv->text);
+       xmlAddChild (xnode, new_xnode);
+}
+
+static void
+atom_generator_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       AtomGenerator *atom_generator = ATOM_GENERATOR (object);
+
+       AtomGeneratorPrivate *priv = ATOM_GENERATOR_GET_PRIVATE (atom_generator);
+
+       switch (property_id)
+               {
+                       case PROP_URI:
+                               priv->uri = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       case PROP_VERSION:
+                               priv->version = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       case PROP_TEXT:
+                               {
+                                       gchar *text = g_strstrip (g_value_dup_string (value));
+                                       if (strcmp (text, "") == 0)
+                                               {
+                                                       g_warning ("Property text must not be empty.");
+                                               }
+                                       else
+                                               {
+                                                       priv->text = text;
+                                               }
+                                       break;
+                               }
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_generator_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       AtomGenerator *atom_generator = ATOM_GENERATOR (object);
+
+       AtomGeneratorPrivate *priv = ATOM_GENERATOR_GET_PRIVATE (atom_generator);
+
+       switch (property_id)
+               {
+                       case PROP_URI:
+                               g_value_set_string (value, priv->uri);
+                               break;
+
+                       case PROP_VERSION:
+                               g_value_set_string (value, priv->version);
+                               break;
+
+                       case PROP_TEXT:
+                               g_value_set_string (value, priv->text);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/atomgenerator.h b/src/atomgenerator.h
new file mode 100644 (file)
index 0000000..246ec98
--- /dev/null
@@ -0,0 +1,64 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_GENERATOR_H__
+#define __ATOM_GENERATOR_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "atomcommon.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM_GENERATOR                 (atom_generator_get_type ())
+#define ATOM_GENERATOR(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM_GENERATOR, AtomGenerator))
+#define ATOM_GENERATOR_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM_GENERATOR, AtomGeneratorClass))
+#define IS_ATOM_GENERATOR(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM_GENERATOR))
+#define IS_ATOM_GENERATOR_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM_GENERATOR))
+#define ATOM_GENERATOR_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM_GENERATOR, AtomGeneratorClass))
+
+
+typedef struct _AtomGenerator AtomGenerator;
+typedef struct _AtomGeneratorClass AtomGeneratorClass;
+
+struct _AtomGenerator
+       {
+               AtomCommon parent;
+       };
+
+struct _AtomGeneratorClass
+       {
+               AtomCommonClass parent_class;
+       };
+
+GType atom_generator_get_type (void) G_GNUC_CONST;
+
+AtomGenerator *atom_generator_new (const gchar *text);
+AtomGenerator *atom_generator_new_from_xml (xmlNode *xnode);
+
+void atom_generator_get_xml (AtomGenerator *atom_generator, xmlNode *xnode);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_GENERATOR_H__ */
diff --git a/src/atomid.c b/src/atomid.c
new file mode 100644 (file)
index 0000000..1dcbfff
--- /dev/null
@@ -0,0 +1,211 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include "atomid.h"
+
+enum
+{
+       PROP_0,
+       PROP_URI
+};
+
+static void atom_id_class_init (AtomIDClass *klass);
+static void atom_id_init (AtomID *atom_id);
+
+static void atom_id_set_property (GObject *object,
+                                  guint property_id,
+                                  const GValue *value,
+                                  GParamSpec *pspec);
+static void atom_id_get_property (GObject *object,
+                                  guint property_id,
+                                  GValue *value,
+                                  GParamSpec *pspec);
+
+#define ATOM_ID_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM_ID, AtomIDPrivate))
+
+typedef struct _AtomIDPrivate AtomIDPrivate;
+struct _AtomIDPrivate
+       {
+               gchar *uri;
+       };
+
+GType
+atom_id_get_type (void)
+{
+       static GType atom_id_type = 0;
+
+       if (!atom_id_type)
+               {
+                       static const GTypeInfo atom_id_info =
+                       {
+                               sizeof (AtomIDClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_id_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (AtomID),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_id_init,
+                               NULL
+                       };
+
+                       atom_id_type = g_type_register_static (TYPE_ATOM_COMMON, "AtomID",
+                                                              &atom_id_info, 0);
+               }
+
+       return atom_id_type;
+}
+
+static void
+atom_id_class_init (AtomIDClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomIDPrivate));
+
+       object_class->set_property = atom_id_set_property;
+       object_class->get_property = atom_id_get_property;
+
+       g_object_class_install_property (object_class, PROP_URI,
+                                        g_param_spec_string ("uri",
+                                                             "URI",
+                                                             "URI",
+                                                             "",
+                                                             G_PARAM_READWRITE));
+}
+
+static void
+atom_id_init (AtomID *atom_id)
+{
+}
+
+/**
+ * atom_id_new:
+ * @uri:
+ *
+ * Returns: the newly created #AtomID object.
+ */
+AtomID
+*atom_id_new (const gchar *uri)
+{
+       gchar *uri_new = "";
+       AtomID *atomid = ATOM_ID (g_object_new (atom_id_get_type (), NULL));
+
+       g_object_set (G_OBJECT (atomid),
+                     "uri", uri,
+                     NULL);
+
+       g_object_get (G_OBJECT (atomid),
+                     "uri", &uri_new,
+                     NULL);
+
+       return (strcmp (uri_new, "") != 0 ? atomid : NULL);
+}
+
+/**
+ * atom_id_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ * Returns: the newly created #AtomID object.
+ */
+AtomID
+*atom_id_new_from_xml (xmlNode *xnode)
+{
+       AtomID *atom_id = NULL;
+
+       gchar *uri = (gchar *)xmlNodeGetContent ((xmlNodePtr)xnode);
+       if (uri != NULL)
+               {
+                       atom_id = atom_id_new (uri);
+                       if (atom_id != NULL)
+                               {
+                                       atom_common_set_properties_from_xml (ATOM_COMMON (atom_id), xnode);
+                               }
+               }
+
+       return atom_id;
+}
+
+/**
+ * atom_id_get_xml:
+ * @atom_id: #AtomID object.
+ * @xnode: an #xmlNode.
+ *
+ */
+void
+atom_id_get_xml (AtomID *atom_id, xmlNode *xnode)
+{
+       AtomIDPrivate *priv = ATOM_ID_GET_PRIVATE (atom_id);
+
+       atom_common_get_xml (ATOM_COMMON (atom_id), xnode);
+
+       xmlNodeSetContent (xnode, (const xmlChar *)priv->uri);
+}
+
+static void
+atom_id_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       AtomID *atom_id = ATOM_ID (object);
+
+       AtomIDPrivate *priv = ATOM_ID_GET_PRIVATE (atom_id);
+
+       switch (property_id)
+               {
+                       case PROP_URI:
+                               {
+                                       gchar *uri = g_value_dup_string (value);
+                                       if (strcmp (g_strstrip (uri), "") != 0)
+                                               {
+                                                       priv->uri = g_strdup (uri);
+                                               }
+                                       else
+                                               {
+                                                       g_warning ("Property uri must not be empty.");
+                                               }
+                                       g_free (uri);
+                                       break;
+                               }
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_id_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       AtomID *atom_id = ATOM_ID (object);
+
+       AtomIDPrivate *priv = ATOM_ID_GET_PRIVATE (atom_id);
+
+       switch (property_id)
+               {
+                       case PROP_URI:
+                               g_value_set_string (value, priv->uri);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/atomid.h b/src/atomid.h
new file mode 100644 (file)
index 0000000..999c311
--- /dev/null
@@ -0,0 +1,64 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_ID_H__
+#define __ATOM_ID_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "atomcommon.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM_ID                 (atom_id_get_type ())
+#define ATOM_ID(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM_ID, AtomID))
+#define ATOM_ID_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM_ID, AtomIDClass))
+#define IS_ATOM_ID(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM_ID))
+#define IS_ATOM_ID_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM_ID))
+#define ATOM_ID_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM_ID, AtomIDClass))
+
+
+typedef struct _AtomID AtomID;
+typedef struct _AtomIDClass AtomIDClass;
+
+struct _AtomID
+       {
+               AtomCommon parent;
+       };
+
+struct _AtomIDClass
+       {
+               AtomCommonClass parent_class;
+       };
+
+GType atom_id_get_type (void) G_GNUC_CONST;
+
+AtomID *atom_id_new (const gchar *uri);
+AtomID *atom_id_new_from_xml (xmlNode *xnode);
+
+void atom_id_get_xml (AtomID *atom_id, xmlNode *xnode);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_ID_H__ */
diff --git a/src/atomlink.c b/src/atomlink.c
new file mode 100644 (file)
index 0000000..3b37482
--- /dev/null
@@ -0,0 +1,360 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include "atomlink.h"
+
+enum
+{
+       PROP_0,
+       PROP_HREF,
+       PROP_REL,
+       PROP_TYPE,
+       PROP_HREFLANG,
+       PROP_TITLE,
+       PROP_LENGTH
+};
+
+static void atom_link_class_init (AtomLinkClass *klass);
+static void atom_link_init (AtomLink *atom_link);
+
+static void atom_link_set_property (GObject *object,
+                                    guint property_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec);
+static void atom_link_get_property (GObject *object,
+                                    guint property_id,
+                                    GValue *value,
+                                    GParamSpec *pspec);
+
+#define ATOM_LINK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM_LINK, AtomLinkPrivate))
+
+typedef struct _AtomLinkPrivate AtomLinkPrivate;
+struct _AtomLinkPrivate
+       {
+               gchar *href,
+                     *rel,
+                     *type,
+                     *hreflang,
+                     *title,
+                     *length;
+       };
+
+GType
+atom_link_get_type (void)
+{
+       static GType atom_link_type = 0;
+
+       if (!atom_link_type)
+               {
+                       static const GTypeInfo atom_link_info =
+                       {
+                               sizeof (AtomLinkClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_link_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (AtomLink),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_link_init,
+                               NULL
+                       };
+
+                       atom_link_type = g_type_register_static (TYPE_ATOM_COMMON, "AtomLink",
+                                                                     &atom_link_info, 0);
+               }
+
+       return atom_link_type;
+}
+
+static void
+atom_link_class_init (AtomLinkClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomLinkPrivate));
+
+       object_class->set_property = atom_link_set_property;
+       object_class->get_property = atom_link_get_property;
+
+       g_object_class_install_property (object_class, PROP_HREF,
+                                        g_param_spec_string ("href",
+                                                             "Href",
+                                                             "Href",
+                                                             "",
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_REL,
+                                        g_param_spec_string ("rel",
+                                                             "Rel",
+                                                             "Indicates the link relation type.",
+                                                             "",
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_TYPE,
+                                        g_param_spec_string ("type",
+                                                             "Type",
+                                                             "An advisory media type: it is a hint about the type of the representation that is expected to be returned when the value of the href attribute is dereferenced.",
+                                                             "",
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_HREFLANG,
+                                        g_param_spec_string ("hreflang",
+                                                             "Hreflang",
+                                                             "Describes the language of the resource pointed to by the href attribute.",
+                                                             "",
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_TITLE,
+                                        g_param_spec_string ("title",
+                                                             "Title",
+                                                             "A human-readable information about the link.",
+                                                             "",
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_LENGTH,
+                                        g_param_spec_string ("length",
+                                                             "Length",
+                                                             "An advisory length of the linked content in octets; it is a hint about the content length of the representation returned when the IRI in the href attribute is mapped to a URI and dereferenced.",
+                                                             "",
+                                                             G_PARAM_READWRITE));
+}
+
+static void
+atom_link_init (AtomLink *atom_link)
+{
+}
+
+/**
+ * atom_link_new:
+ * @href:
+ *
+ * Returns: the newly created #AtomLink object.
+ */
+AtomLink
+*atom_link_new (const gchar *href)
+{
+       AtomLink *atom_link = ATOM_LINK (g_object_new (atom_link_get_type (), NULL));
+
+       g_object_set (G_OBJECT (atom_link),
+                     "href", href,
+                     NULL);
+
+       return atom_link;
+}
+
+/**
+ * atom_link_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ * Returns: the newly created #AtomLink object.
+ */
+AtomLink
+*atom_link_new_from_xml (xmlNode *xnode)
+{
+       AtomLink *atom_link = NULL;
+
+       gchar *href = (gchar *)xmlGetProp (xnode, (const xmlChar *)"href");
+       if (href == NULL || strcmp (g_strstrip (href), "") == 0)
+               {
+                       g_critical ("AtomLink must have an href attribute.");
+                       return NULL;
+               }
+       else
+               {
+                       atom_link = atom_link_new (href);
+                       if (atom_link != NULL)
+                               {
+                                       atom_common_set_properties_from_xml (ATOM_COMMON (atom_link), xnode);
+
+                                       href = (gchar *)xmlGetProp (xnode, (const xmlChar *)"rel");
+                                       if (href != NULL && strcmp (g_strstrip (href), "") != 0)
+                                               {
+                                                       g_object_set (G_OBJECT (atom_link),
+                                                                     "rel", href,
+                                                                     NULL);
+                                               }
+
+                                       href = (gchar *)xmlGetProp (xnode, (const xmlChar *)"type");
+                                       if (href != NULL && strcmp (g_strstrip (href), "") != 0)
+                                               {
+                                                       g_object_set (G_OBJECT (atom_link),
+                                                                     "type", href,
+                                                                     NULL);
+                                               }
+
+                                       href = (gchar *)xmlGetProp (xnode, (const xmlChar *)"hreflang");
+                                       if (href != NULL && strcmp (g_strstrip (href), "") != 0)
+                                               {
+                                                       g_object_set (G_OBJECT (atom_link),
+                                                                     "hreflang", href,
+                                                                     NULL);
+                                               }
+
+                                       href = (gchar *)xmlGetProp (xnode, (const xmlChar *)"title");
+                                       if (href != NULL && strcmp (g_strstrip (href), "") != 0)
+                                               {
+                                                       g_object_set (G_OBJECT (atom_link),
+                                                                     "title", href,
+                                                                     NULL);
+                                               }
+
+                                       href = (gchar *)xmlGetProp (xnode, (const xmlChar *)"length");
+                                       if (href != NULL && strcmp (g_strstrip (href), "") != 0)
+                                               {
+                                                       g_object_set (G_OBJECT (atom_link),
+                                                                     "length", href,
+                                                                     NULL);
+                                               }
+                               }
+               }
+
+       return atom_link;
+}
+
+/**
+ * atom_link_get_xml:
+ * @atom_link: an #AtomLink object.
+ * @xnode: an #xmlNode.
+ *
+ */
+void
+atom_link_get_xml (AtomLink *atom_link, xmlNode *xnode)
+{
+       xmlNode *new_xnode;
+
+       AtomLinkPrivate *priv = ATOM_LINK_GET_PRIVATE (atom_link);
+
+       atom_common_get_xml (ATOM_COMMON (atom_link), xnode);
+
+       if (strcmp (priv->href, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"href", (const xmlChar *)priv->href);
+               }
+       if (strcmp (priv->rel, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"rel", (const xmlChar *)priv->rel);
+               }
+       if (strcmp (priv->type, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"type", (const xmlChar *)priv->type);
+               }
+       if (strcmp (priv->hreflang, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"hreflang", (const xmlChar *)priv->hreflang);
+               }
+       if (strcmp (priv->title, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"title", (const xmlChar *)priv->title);
+               }
+       if (strcmp (priv->length, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"length", (const xmlChar *)priv->length);
+               }
+}
+
+static void
+atom_link_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       AtomLink *atom_link = ATOM_LINK (object);
+
+       AtomLinkPrivate *priv = ATOM_LINK_GET_PRIVATE (atom_link);
+
+       switch (property_id)
+               {
+                       case PROP_HREF:
+                               {
+                                       gchar *href = g_strstrip (g_value_dup_string (value));
+                                       if (strcmp (href, "") == 0)
+                                               {
+                                                       g_warning ("Property href must not be empty.");
+                                               }
+                                       else
+                                               {
+                                                       priv->href = href;
+                                               }
+                                       break;
+                               }
+
+                       case PROP_REL:
+                               priv->rel = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       case PROP_TYPE:
+                               priv->type = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       case PROP_HREFLANG:
+                               priv->hreflang = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       case PROP_TITLE:
+                               priv->title = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       case PROP_LENGTH:
+                               priv->length = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_link_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       AtomLink *atom_link = ATOM_LINK (object);
+
+       AtomLinkPrivate *priv = ATOM_LINK_GET_PRIVATE (atom_link);
+
+       switch (property_id)
+               {
+                       case PROP_HREF:
+                               g_value_set_string (value, priv->href);
+                               break;
+
+                       case PROP_REL:
+                               g_value_set_string (value, priv->rel);
+                               break;
+
+                       case PROP_TYPE:
+                               g_value_set_string (value, priv->type);
+                               break;
+
+                       case PROP_HREFLANG:
+                               g_value_set_string (value, priv->hreflang);
+                               break;
+
+                       case PROP_TITLE:
+                               g_value_set_string (value, priv->title);
+                               break;
+
+                       case PROP_LENGTH:
+                               g_value_set_string (value, priv->length);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/atomlink.h b/src/atomlink.h
new file mode 100644 (file)
index 0000000..a7c1e5f
--- /dev/null
@@ -0,0 +1,64 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_LINK_H__
+#define __ATOM_LINK_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "atomcommon.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM_LINK                 (atom_link_get_type ())
+#define ATOM_LINK(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM_LINK, AtomLink))
+#define ATOM_LINK_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM_LINK, AtomLinkClass))
+#define IS_ATOM_LINK(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM_LINK))
+#define IS_ATOM_LINK_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM_LINK))
+#define ATOM_LINK_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM_LINK, AtomLinkClass))
+
+
+typedef struct _AtomLink AtomLink;
+typedef struct _AtomLinkClass AtomLinkClass;
+
+struct _AtomLink
+       {
+               AtomCommon parent;
+       };
+
+struct _AtomLinkClass
+       {
+               AtomCommonClass parent_class;
+       };
+
+GType atom_link_get_type (void) G_GNUC_CONST;
+
+AtomLink *atom_link_new (const gchar *href);
+AtomLink *atom_link_new_from_xml (xmlNode *xnode);
+
+void atom_link_get_xml (AtomLink *atom_link, xmlNode *xnode);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_LINK_H__ */
diff --git a/src/atomperson.c b/src/atomperson.c
new file mode 100644 (file)
index 0000000..26529f2
--- /dev/null
@@ -0,0 +1,296 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <libxml/xpath.h>
+
+#include "atomperson.h"
+
+enum
+{
+       PROP_0,
+       PROP_NAME,
+       PROP_URI,
+       PROP_EMAIL
+};
+
+static void atom_person_class_init (AtomPersonClass *klass);
+static void atom_person_init (AtomPerson *atom_person);
+
+static void atom_person_set_property (GObject *object,
+                                    guint property_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec);
+static void atom_person_get_property (GObject *object,
+                                    guint property_id,
+                                    GValue *value,
+                                    GParamSpec *pspec);
+
+#define ATOM_PERSON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM_PERSON, AtomPersonPrivate))
+
+typedef struct _AtomPersonPrivate AtomPersonPrivate;
+struct _AtomPersonPrivate
+       {
+               gchar *name,
+                     *uri,
+                     *email;
+       };
+
+GType
+atom_person_get_type (void)
+{
+       static GType atom_person_type = 0;
+
+       if (!atom_person_type)
+               {
+                       static const GTypeInfo atom_person_info =
+                       {
+                               sizeof (AtomPersonClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_person_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (AtomPerson),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_person_init,
+                               NULL
+                       };
+
+                       atom_person_type = g_type_register_static (TYPE_ATOM_COMMON, "AtomPerson",
+                                                                  &atom_person_info, 0);
+               }
+
+       return atom_person_type;
+}
+
+static void
+atom_person_class_init (AtomPersonClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomPersonPrivate));
+
+       object_class->set_property = atom_person_set_property;
+       object_class->get_property = atom_person_get_property;
+
+       g_object_class_install_property (object_class, PROP_NAME,
+                                        g_param_spec_string ("name",
+                                                             "Name",
+                                                             "Conveys a human-readable name for the person.",
+                                                             "",
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_URI,
+                                        g_param_spec_string ("uri",
+                                                             "URI",
+                                                             "Conveys an IRI associated with the person.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       g_object_class_install_property (object_class, PROP_EMAIL,
+                                        g_param_spec_string ("email",
+                                                             "EMail",
+                                                             "Conveys an e-mail address associated with the person.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+atom_person_init (AtomPerson *atom_person)
+{
+}
+
+/**
+ * atom_person_new:
+ * @name: a string with a human-readable name for the person.
+ *
+ * Returns: the newly created #AtomPerson object.
+ */
+AtomPerson
+*atom_person_new (const gchar *name)
+{
+       AtomPerson *atom_person = ATOM_PERSON (g_object_new (atom_person_get_type (), NULL));
+
+       g_object_set (G_OBJECT (atom_person),
+                     "name", name,
+                     NULL);
+
+       return atom_person;
+}
+
+/**
+ * atom_person_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ * Returns: the newly created #AtomPerson object.
+ */
+AtomPerson
+*atom_person_new_from_xml (xmlNode *xnode)
+{
+       gchar *name;
+
+       AtomPerson *atom_person = NULL;
+
+       xmlXPathObjectPtr xpresult;
+       xmlXPathContextPtr xpcontext = xmlXPathNewContext (xnode->doc);
+
+       xmlXPathRegisterNs (xpcontext, (const xmlChar *)"atom", (const xmlChar *)"http://www.w3.org/2005/Atom");
+
+       xpcontext->node = xnode;
+       xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::atom:name", xpcontext);
+       if (xpresult == NULL || xpresult->nodesetval == NULL || xpresult->nodesetval->nodeNr != 1)
+               {
+                       g_critical ("AtomPerson must have a name element.");
+                       return NULL;
+               }
+       else
+               {
+                       name = (gchar *)xmlNodeGetContent ((xmlNodePtr)xpresult->nodesetval->nodeTab[0]);
+                       if (strcmp (g_strstrip (name), "") == 0)
+                               {
+                                       g_critical ("Element name must be filled.");
+                                       return NULL;
+                               }
+               }
+
+       atom_person = atom_person_new (name);
+       if (atom_person != NULL)
+               {
+                       atom_common_set_properties_from_xml (ATOM_COMMON (atom_person), xnode);
+
+                       xpcontext->node = xnode;
+                       xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::atom:uri", xpcontext);
+                       if (xpresult != NULL && xpresult->nodesetval != NULL && xpresult->nodesetval->nodeNr != 0)
+                               {
+                                       g_object_set (G_OBJECT (atom_person),
+                                                     "uri", (gchar *)xmlNodeGetContent ((xmlNodePtr)xpresult->nodesetval->nodeTab[0]),
+                                                     NULL);
+                               }
+
+                       xpcontext->node = xnode;
+                       xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::atom:email", xpcontext);
+                       if (xpresult != NULL && xpresult->nodesetval != NULL && xpresult->nodesetval->nodeNr != 0)
+                               {
+                                       g_object_set (G_OBJECT (atom_person),
+                                                     "email", (gchar *)xmlNodeGetContent ((xmlNodePtr)xpresult->nodesetval->nodeTab[0]),
+                                                     NULL);
+                               }
+               }
+
+       return atom_person;
+}
+
+/**
+ * atom_person_get_xml:
+ * @atom_person: an #AtomPerson object.
+ * @xnode: an #xmlNode.
+ *
+ */
+void
+atom_person_get_xml (AtomPerson *atom_person, xmlNode *xnode)
+{
+       xmlNode *new_xnode;
+
+       AtomPersonPrivate *priv = ATOM_PERSON_GET_PRIVATE (atom_person);
+
+       atom_common_get_xml (ATOM_COMMON (atom_person), xnode);
+
+       new_xnode = xmlNewNode (NULL, (const xmlChar *)"name");
+       xmlNodeSetContent (new_xnode, (const xmlChar *)priv->name);
+       xmlAddChild (xnode, new_xnode);
+
+       if (strcmp (priv->uri, "") != 0)
+               {
+                       new_xnode = xmlNewNode (NULL, (const xmlChar *)"uri");
+                       xmlNodeSetContent (new_xnode, (const xmlChar *)priv->uri);
+                       xmlAddChild (xnode, new_xnode);
+               }
+       if (strcmp (priv->email, "") != 0)
+               {
+                       new_xnode = xmlNewNode (NULL, (const xmlChar *)"email");
+                       xmlNodeSetContent (new_xnode, (const xmlChar *)priv->email);
+                       xmlAddChild (xnode, new_xnode);
+               }
+}
+
+static void
+atom_person_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       AtomPerson *atom_person = ATOM_PERSON (object);
+
+       AtomPersonPrivate *priv = ATOM_PERSON_GET_PRIVATE (atom_person);
+
+       switch (property_id)
+               {
+                       case PROP_NAME:
+                               {
+                                       gchar *name = g_strstrip (g_value_dup_string (value));
+                                       if (strcmp (name, "") == 0)
+                                               {
+                                                       g_warning ("Property name must not be empty.");
+                                               }
+                                       else
+                                               {
+                                                       priv->name = name;
+                                               }
+                                       break;
+                               }
+
+                       case PROP_URI:
+                               priv->uri = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       case PROP_EMAIL:
+                               priv->email = g_strstrip (g_value_dup_string (value));
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_person_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       AtomPerson *atom_person = ATOM_PERSON (object);
+
+       AtomPersonPrivate *priv = ATOM_PERSON_GET_PRIVATE (atom_person);
+
+       switch (property_id)
+               {
+                       case PROP_NAME:
+                               g_value_set_string (value, priv->name);
+                               break;
+
+                       case PROP_URI:
+                               g_value_set_string (value, priv->uri);
+                               break;
+
+                       case PROP_EMAIL:
+                               g_value_set_string (value, priv->email);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/atomperson.h b/src/atomperson.h
new file mode 100644 (file)
index 0000000..975d261
--- /dev/null
@@ -0,0 +1,64 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_PERSON_H__
+#define __ATOM_PERSON_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "atomcommon.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM_PERSON                 (atom_person_get_type ())
+#define ATOM_PERSON(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM_PERSON, AtomPerson))
+#define ATOM_PERSON_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM_PERSON, AtomPersonClass))
+#define IS_ATOM_PERSON(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM_PERSON))
+#define IS_ATOM_PERSON_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM_PERSON))
+#define ATOM_PERSON_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM_PERSON, AtomPersonClass))
+
+
+typedef struct _AtomPerson AtomPerson;
+typedef struct _AtomPersonClass AtomPersonClass;
+
+struct _AtomPerson
+       {
+               AtomCommon parent;
+       };
+
+struct _AtomPersonClass
+       {
+               AtomCommonClass parent_class;
+       };
+
+GType atom_person_get_type (void) G_GNUC_CONST;
+
+AtomPerson *atom_person_new (const gchar *name);
+AtomPerson *atom_person_new_from_xml (xmlNode *xnode);
+
+void atom_person_get_xml (AtomPerson *atom_person, xmlNode *xnode);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_PERSON_H__ */
diff --git a/src/atomsource.c b/src/atomsource.c
new file mode 100644 (file)
index 0000000..9cd1e45
--- /dev/null
@@ -0,0 +1,590 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include "atomsource.h"
+#include "atomperson.h"
+#include "atomcategory.h"
+#include "atomgenerator.h"
+#include "atomlink.h"
+
+enum
+{
+       PROP_0,
+       PROP_AUTHOR,
+       PROP_CATEGORY,
+       PROP_CONTRIBUTOR,
+       PROP_GENERATOR,
+       PROP_ICON,
+       PROP_ID,
+       PROP_LINK,
+       PROP_LOGO,
+       PROP_RIGHTS,
+       PROP_SUBTITLE,
+       PROP_TITLE,
+       PROP_UPDATED
+};
+
+static void atom_source_class_init (AtomSourceClass *klass);
+static void atom_source_init (AtomSource *atome);
+
+static void atom_source_set_property (GObject *object,
+                                      guint property_id,
+                                      const GValue *value,
+                                      GParamSpec *pspec);
+static void atom_source_get_property (GObject *object,
+                                      guint property_id,
+                                      GValue *value,
+                                      GParamSpec *pspec);
+
+#define ATOM_SOURCE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM_SOURCE, AtomSourcePrivate))
+
+typedef struct _AtomSourcePrivate AtomSourcePrivate;
+struct _AtomSourcePrivate
+       {
+               GList *author,
+                     *category,
+                     *contributor;
+               AtomGenerator *generator;
+               AtomID *icon,
+                      *id,
+                      *logo;
+               AtomLink *link;
+               AtomText *title,
+                        *rights,
+                        *subtitle;
+               AtomDate *updated;
+       };
+
+GType
+atom_source_get_type (void)
+{
+       static GType atom_source_type = 0;
+
+       if (!atom_source_type)
+               {
+                       static const GTypeInfo atom_source_info =
+                       {
+                               sizeof (AtomSourceClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_source_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (AtomSource),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_source_init,
+                               NULL
+                       };
+
+                       atom_source_type = g_type_register_static (TYPE_ATOM_COMMON, "AtomSource",
+                                                                  &atom_source_info, 0);
+               }
+
+       return atom_source_type;
+}
+
+static void
+atom_source_class_init (AtomSourceClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomSourcePrivate));
+
+       object_class->set_property = atom_source_set_property;
+       object_class->get_property = atom_source_get_property;
+
+       g_object_class_install_property (object_class, PROP_AUTHOR,
+                                        g_param_spec_pointer ("author",
+                                                              "Author",
+                                                              "A #GList of #AtomPerson objects that indicates the author of the entry or feed.",
+                                                              G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_CATEGORY,
+                                        g_param_spec_pointer ("category",
+                                                              "Category",
+                                                              "A #GList of #AtomCategory objects convey information about a category associated with an entry or feed.",
+                                                              G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_CONTRIBUTOR,
+                                        g_param_spec_pointer ("contributor",
+                                                              "Contributor",
+                                                              "A #GList of #AtomPerson objects that indicate a person or other entity who contributed to the entry or feed.",
+                                                              G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_GENERATOR,
+                                        g_param_spec_object ("generator",
+                                                             "Generato",
+                                                             "An #AtomGenerator object that identifies the agent used to generate a feed, for debugging and other purposes.",
+                                                             TYPE_ATOM_GENERATOR,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_ICON,
+                                        g_param_spec_object ("icon",
+                                                             "Icon",
+                                                             "An #AtomID object that contains an IRI reference [RFC3987] that identifies an image that provides iconic visual identification for a feed.",
+                                                             TYPE_ATOM_ID,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_ID,
+                                        g_param_spec_object ("id",
+                                                             "Id",
+                                                             "An #AtomID object that conveys a permanent, universally unique identifier for an entry or feed.",
+                                                             TYPE_ATOM_ID,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_LINK,
+                                        g_param_spec_object ("link",
+                                                             "Link",
+                                                             "An #AtomLink object that defines a reference from an entry or feed to a Web resource.",
+                                                             TYPE_ATOM_LINK,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_LOGO,
+                                        g_param_spec_object ("logo",
+                                                             "Logo",
+                                                             "An #AtonID object that contains an IRI reference [RFC3987] that identifies an image that provides visual identification for a feed.",
+                                                             TYPE_ATOM_ID,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_RIGHTS,
+                                        g_param_spec_object ("rights",
+                                                             "Rights",
+                                                             "An #AtomText object that conveys information about rights held in and over an entry or feed.",
+                                                             TYPE_ATOM_TEXT,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_SUBTITLE,
+                                        g_param_spec_object ("subtitle",
+                                                             "Subtitle",
+                                                             "An #AtomText object that conveys a human-readable description or subtitle for a feed.",
+                                                             TYPE_ATOM_TEXT,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_TITLE,
+                                        g_param_spec_object ("title",
+                                                             "Title",
+                                                             "An #AtomText object that conveys a human-readable title for an entry or feed.",
+                                                             TYPE_ATOM_TEXT,
+                                                             G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class, PROP_UPDATED,
+                                        g_param_spec_object ("updated",
+                                                             "Updated",
+                                                             "An #AtomDate object indicating the most recent instant in time when an entry or feed was modified in a way the publisher considers significant.",
+                                                             TYPE_ATOM_DATE,
+                                                             G_PARAM_READWRITE));
+}
+
+static void
+atom_source_init (AtomSource *atome)
+{
+}
+
+/**
+ * atom_source_new:
+ *
+ * Returns: the newly created #AtomSource object.
+ */
+AtomSource
+*atom_source_new ()
+{
+       return ATOM_SOURCE (g_object_new (atom_source_get_type (), NULL));
+}
+
+/**
+ * atom_source_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ * Returns: the newly created #AtomSource object.
+ */
+AtomSource
+*atom_source_new_from_xml (xmlNode *xnode)
+{
+       AtomSource *atom_source = atom_source_new ();
+
+       AtomSourcePrivate *priv = ATOM_SOURCE_GET_PRIVATE (atom_source);
+
+       atom_common_set_properties_from_xml (ATOM_COMMON (atom_source), xnode);
+
+       xmlNode *cur = xnode->children;
+
+       while (cur != NULL)
+               {
+                       if (xmlStrcmp (cur->name, (const xmlChar *)"author") == 0)
+                               {
+                                       AtomPerson *ap = atom_person_new_from_xml (cur);
+                                       if (ap != NULL)
+                                               {
+                                                       priv->author = g_list_append (priv->author, ap);
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"category") == 0)
+                               {
+                                       AtomCategory *ac = atom_category_new_from_xml (cur);
+                                       if (ac != NULL)
+                                               {
+                                                       priv->category = g_list_append (priv->category, ac);
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"contributor") == 0)
+                               {
+                                       AtomPerson *ap = atom_person_new_from_xml (cur);
+                                       if (ap != NULL)
+                                               {
+                                                       priv->contributor = g_list_append (priv->contributor, ap);
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"generator") == 0)
+                               {
+                                       AtomGenerator *ag = atom_generator_new_from_xml (cur);
+                                       if (ag != NULL)
+                                               {
+                                                       priv->generator = ag;
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"icon") == 0)
+                               {
+                                       AtomID *icon = atom_id_new_from_xml (cur);
+                                       if (icon == NULL)
+                                               {
+                                                       priv->icon = icon;
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"link") == 0)
+                               {
+                                       AtomLink *link = atom_link_new_from_xml (cur);
+                                       if (link == NULL)
+                                               {
+                                                       priv->link = link;
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"logo") == 0)
+                               {
+                                       AtomID *logo = atom_id_new_from_xml (cur);
+                                       if (logo == NULL)
+                                               {
+                                                       priv->logo = logo;
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"rights") == 0)
+                               {
+                                       AtomText *rights = atom_text_new_from_xml (cur);
+                                       if (rights != NULL)
+                                               {
+                                                       priv->rights = rights;
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"subtitle") == 0)
+                               {
+                                       AtomText *subtitle = atom_text_new_from_xml (cur);
+                                       if (subtitle != NULL)
+                                               {
+                                                       priv->subtitle = subtitle;
+                                               }
+                               }
+
+                       cur = cur->next;
+               }
+
+       return atom_source;
+}
+
+/**
+ * atatom_source_get_xml:
+ * @atom_source: an #AtomSource object.
+ *
+ */
+void
+atom_source_get_xml (AtomSource *atom_source, xmlNode *xnode)
+{
+       xmlNode *xnodenew;
+       GList *lst;
+
+       AtomSourcePrivate *priv = ATOM_SOURCE_GET_PRIVATE (atom_source);
+
+       atom_common_get_xml (ATOM_COMMON (atom_source), xnodenew);
+
+       lst = g_list_first (priv->author);
+       while (lst != NULL)
+               {
+                       if (IS_ATOM_PERSON (lst->data))
+                               {
+                                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"author");
+                                       xmlAddChild (xnode, xnodenew);
+                                       atom_person_get_xml (ATOM_PERSON (lst->data), xnodenew);
+                               }
+
+                       lst = g_list_next (lst);
+               }
+
+       lst = g_list_first (priv->category);
+       while (lst != NULL)
+               {
+                       if (IS_ATOM_CATEGORY (lst->data))
+                               {
+                                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"category");
+                                       xmlAddChild (xnode, xnodenew);
+                                       atom_category_get_xml (ATOM_CATEGORY (lst->data), xnodenew);
+                               }
+
+                       lst = g_list_next (lst);
+               }
+
+       lst = g_list_first (priv->contributor);
+       while (lst != NULL)
+               {
+                       if (IS_ATOM_PERSON (lst->data))
+                               {
+                                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"contributor");
+                                       xmlAddChild (xnode, xnodenew);
+                                       atom_person_get_xml (ATOM_PERSON (lst->data), xnodenew);
+                               }
+
+                       lst = g_list_next (lst);
+               }
+
+       if (priv->generator != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"generator");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_generator_get_xml (priv->generator, xnodenew);             
+               }
+
+       if (priv->icon != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"icon");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_id_get_xml (priv->icon, xnodenew);
+               }
+
+       if (priv->id != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"id");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_id_get_xml (priv->id, xnodenew);
+               }
+
+       if (priv->link != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"link");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_link_get_xml (priv->link, xnodenew);
+               }
+
+       if (priv->logo != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"logo");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_id_get_xml (priv->logo, xnodenew);
+               }
+
+       if (priv->rights != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"rights");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_text_get_xml (priv->rights, xnodenew);
+               }
+
+       if (priv->subtitle != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"subtitle");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_text_get_xml (priv->subtitle, xnodenew);
+               }
+
+       if (priv->title != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"title");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_text_get_xml (priv->title, xnodenew);
+               }
+
+       if (priv->updated != NULL)
+               {
+                       xnodenew = xmlNewNode (NULL, (const xmlChar *)"updated");
+                       xmlAddChild (xnode, xnodenew);
+                       atom_date_get_xml (priv->updated, xnodenew);
+               }
+}
+
+static void
+atom_source_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       GObject *obj;
+
+       AtomSource *atome = ATOM_SOURCE (object);
+
+       AtomSourcePrivate *priv = ATOM_SOURCE_GET_PRIVATE (atome);
+
+       switch (property_id)
+               {
+                       case PROP_AUTHOR:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->author = (GList *)g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (GList));
+                                       }
+                               break;
+
+                       case PROP_CATEGORY:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->category = (GList *)g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (GList));
+                                       }
+                               break;
+
+                       case PROP_CONTRIBUTOR:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->contributor = (GList *)g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (GList));
+                                       }
+                               break;
+
+                       case PROP_GENERATOR:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_GENERATOR (g_value_get_object (value)))
+                                       {
+                                               priv->generator = (AtomGenerator *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_ICON:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_ID (g_value_get_object (value)))
+                                       {
+                                               priv->icon = (AtomID *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_ID:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_ID (g_value_get_object (value)))
+                                       {
+                                               priv->id = (AtomID *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_LINK:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_LINK (g_value_get_object (value)))
+                                       {
+                                               priv->link = (AtomLink *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_LOGO:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_ID (g_value_get_object (value)))
+                                       {
+                                               priv->logo = (AtomID *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_RIGHTS:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_TEXT (g_value_get_object (value)))
+                                       {
+                                               priv->rights = (AtomText *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_SUBTITLE:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_TEXT (g_value_get_object (value)))
+                                       {
+                                               priv->subtitle = (AtomText *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_TITLE:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_TEXT (g_value_get_object (value)))
+                                       {
+                                               priv->title = (AtomText *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_UPDATED:
+                               if (g_value_get_object (value) != NULL && IS_ATOM_DATE (g_value_get_object (value)))
+                                       {
+                                               priv->updated = (AtomDate *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_source_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       AtomSource *atome = ATOM_SOURCE (object);
+
+       AtomSourcePrivate *priv = ATOM_SOURCE_GET_PRIVATE (atome);
+       
+       switch (property_id)
+               {
+                       case PROP_AUTHOR:
+                               g_value_set_pointer (value, priv->author);
+                               break;
+
+                       case PROP_CATEGORY:
+                               g_value_set_pointer (value, priv->category);
+                               break;
+
+                       case PROP_CONTRIBUTOR:
+                               g_value_set_pointer (value, priv->contributor);
+                               break;
+
+                       case PROP_GENERATOR:
+                               g_value_set_pointer (value, priv->generator);
+                               break;
+
+                       case PROP_ICON:
+                               g_value_set_object (value, priv->icon);
+                               break;
+
+                       case PROP_ID:
+                               g_value_set_object (value, priv->id);
+                               break;
+
+                       case PROP_LINK:
+                               g_value_set_object (value, priv->link);
+                               break;
+
+                       case PROP_LOGO:
+                               g_value_set_object (value, priv->logo);
+                               break;
+
+                       case PROP_RIGHTS:
+                               g_value_set_object (value, priv->rights);
+                               break;
+
+                       case PROP_SUBTITLE:
+                               g_value_set_object (value, priv->subtitle);
+                               break;
+
+                       case PROP_TITLE:
+                               g_value_set_object (value, priv->title);
+                               break;
+
+                       case PROP_UPDATED:
+                               g_value_set_object (value, priv->updated);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/atomsource.h b/src/atomsource.h
new file mode 100644 (file)
index 0000000..e6eeb45
--- /dev/null
@@ -0,0 +1,68 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_SOURCE_H__
+#define __ATOM_SOURCE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+#include "atomcommon.h"
+#include "atomid.h"
+#include "atomtext.h"
+#include "atomdate.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM_SOURCE                 (atom_source_get_type ())
+#define ATOM_SOURCE(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM_SOURCE, AtomSource))
+#define ATOM_SOURCE_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM_SOURCE, AtomSourceClass))
+#define IS_ATOM_SOURCE(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM_SOURCE))
+#define IS_ATOM_SOURCE_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM_SOURCE))
+#define ATOM_SOURCE_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM_SOURCE, AtomSourceClass))
+
+
+typedef struct _AtomSource AtomSource;
+typedef struct _AtomSourceClass AtomSourceClass;
+
+struct _AtomSource
+       {
+               AtomCommon parent;
+       };
+
+struct _AtomSourceClass
+       {
+               AtomCommonClass parent_class;
+       };
+
+GType atom_source_get_type (void) G_GNUC_CONST;
+
+AtomSource *atom_source_new (void);
+AtomSource *atom_source_new_from_xml (xmlNode *xnode);
+
+void atom_source_get_xml (AtomSource *atom_source, xmlNode *xnode);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_SOURCE_H__ */
diff --git a/src/atomtext.c b/src/atomtext.c
new file mode 100644 (file)
index 0000000..79387ca
--- /dev/null
@@ -0,0 +1,287 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <libxml/xpath.h>
+
+#include "atomtext.h"
+
+enum
+{
+       PROP_0,
+       PROP_TYPE,
+       PROP_TEXT
+};
+
+static void atom_text_class_init (AtomTextClass *klass);
+static void atom_text_init (AtomText *atom_text);
+
+static void atom_text_set_property (GObject *object,
+                                    guint property_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec);
+static void atom_text_get_property (GObject *object,
+                                    guint property_id,
+                                    GValue *value,
+                                    GParamSpec *pspec);
+
+#define ATOM_TEXT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_ATOM_TEXT, AtomTextPrivate))
+
+typedef struct _AtomTextPrivate AtomTextPrivate;
+struct _AtomTextPrivate
+       {
+               AtomTextType type;
+               gchar *text;
+       };
+
+GType
+atom_text_get_type (void)
+{
+       static GType atom_text_type = 0;
+
+       if (!atom_text_type)
+               {
+                       static const GTypeInfo atom_text_info =
+                       {
+                               sizeof (AtomTextClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) atom_text_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (AtomText),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) atom_text_init,
+                               NULL
+                       };
+
+                       atom_text_type = g_type_register_static (TYPE_ATOM_COMMON, "AtomText",
+                                                                &atom_text_info, 0);
+               }
+
+       return atom_text_type;
+}
+
+static void
+atom_text_class_init (AtomTextClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (AtomTextPrivate));
+
+       object_class->set_property = atom_text_set_property;
+       object_class->get_property = atom_text_get_property;
+
+       g_object_class_install_property (object_class, PROP_TYPE,
+                                        g_param_spec_uint ("type",
+                                                           "Type",
+                                                           "Type",
+                                                           0, 2, 0,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+       g_object_class_install_property (object_class, PROP_TEXT,
+                                        g_param_spec_string ("text",
+                                                             "Text",
+                                                             "Text",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+atom_text_init (AtomText *atom_text)
+{
+}
+
+/**
+ * atom_text_new:
+ *
+ * Returns: the newly created #AtomText object.
+ */
+AtomText
+*atom_text_new (AtomTextType type, const gchar *text)
+{
+       AtomText *atomtext = ATOM_TEXT (g_object_new (atom_text_get_type (), NULL));
+
+       g_object_set (G_OBJECT (atomtext),
+                     "type", type,
+                     "text", text,
+                     NULL);
+
+       return atomtext;
+}
+
+/**
+ * atom_text_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ * Returns: the newly created #AtomText object.
+ */
+AtomText
+*atom_text_new_from_xml (xmlNode *xnode)
+{
+       AtomText *atom_text = NULL;
+       AtomTextType atomtype;
+       gchar *text;
+
+       gchar *type = (gchar *)xmlGetProp ((xmlNodePtr)xnode, (const xmlChar *)"type");
+       if (type == NULL || strcmp (type, "text") == 0)
+               {
+                       atomtype = ATOM_TEXT_TEXT;
+               }
+       else if (strcmp (type, "html") == 0)
+               {
+                       atomtype = ATOM_TEXT_HTML;
+               }
+       else if (strcmp (type, "xhtml") == 0)
+               {
+                       atomtype = ATOM_TEXT_XHTML;
+               }
+       else
+               {
+                       g_critical ("Invalid AtomText type.");
+                       return NULL;
+               }
+
+       if (atomtype == ATOM_TEXT_TEXT || atomtype == ATOM_TEXT_HTML)
+               {
+                       text = (gchar *)xmlNodeGetContent ((xmlNodePtr)xnode);
+               }
+       else if (atomtype == ATOM_TEXT_XHTML)
+               {
+                       xmlXPathObjectPtr xpresult;
+                       xmlXPathContextPtr xpcontext = xmlXPathNewContext (xnode->doc);
+
+                       xmlXPathRegisterNs (xpcontext, (const xmlChar *)"xhtml", (const xmlChar *)"http://www.w3.org/1999/xhtml");
+
+                       xpcontext->node = xnode;
+                       xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::xhtml:div", xpcontext);
+                       if (xpresult == NULL || xpresult->nodesetval->nodeNr != 1)
+                               {
+                                       g_critical ("Invalid AtomText type xhtml.");
+                                       return NULL;
+                               }
+                       else
+                               {
+                                       text = (gchar *)xmlNodeGetContent ((xmlNodePtr)xpresult->nodesetval->nodeTab[0]);
+                               }
+               }
+
+       if (text != NULL)
+               {
+                       atom_text = atom_text_new (atomtype, g_strstrip (text));
+                       if (atom_text != NULL)
+                               {
+                                       atom_common_set_properties_from_xml (ATOM_COMMON (atom_text), xnode);
+                               }
+               }
+
+       return atom_text;
+}
+
+/**
+ * atom_text_get_xml:
+ * @atom_text: #AtomText object.
+ * @xnode:
+ *
+ */
+void
+atom_text_get_xml (AtomText *atom_text, xmlNode *xnode)
+{
+       gchar *type;
+
+       AtomTextPrivate *priv = ATOM_TEXT_GET_PRIVATE (atom_text);
+
+       atom_common_get_xml (ATOM_COMMON (atom_text), xnode);
+
+       switch (priv->type)
+               {
+                       case ATOM_TEXT_TEXT:
+                               type = g_strdup ("text");
+                               break;
+
+                       case ATOM_TEXT_HTML:
+                               type = g_strdup ("html");
+                               break;
+
+                       case ATOM_TEXT_XHTML:
+                               type = g_strdup ("xhtml");
+                               break;
+               }
+
+       xmlSetProp (xnode, (const xmlChar *)"type", (const xmlChar *)type);
+       
+       if (priv->type == ATOM_TEXT_XHTML)
+               {
+                       xmlNode *new_xnode = xmlNewNode (NULL, (const xmlChar *)"xhtml:div");
+                       xmlNewNs (new_xnode, (const xmlChar *)"http://www.w3.org/1999/xhtml", (const xmlChar *)"xhtml");
+                       xmlNodeSetContent (new_xnode, (const xmlChar *)priv->text);
+                       xmlAddChild (xnode, new_xnode);
+               }
+       else
+               {
+                       xmlNodeSetContent (xnode, (const xmlChar *)priv->text);
+               }
+}
+
+static void
+atom_text_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       AtomText *atom_text = ATOM_TEXT (object);
+
+       AtomTextPrivate *priv = ATOM_TEXT_GET_PRIVATE (atom_text);
+
+       switch (property_id)
+               {
+                       case PROP_TYPE:
+                               priv->type = g_value_get_uint (value);
+                               break;
+
+                       case PROP_TEXT:
+                               priv->text = g_value_dup_string (value);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+atom_text_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       AtomText *atom_text = ATOM_TEXT (object);
+
+       AtomTextPrivate *priv = ATOM_TEXT_GET_PRIVATE (atom_text);
+
+       switch (property_id)
+               {
+                       case PROP_TYPE:
+                               g_value_set_int (value, priv->type);
+                               break;
+
+                       case PROP_TEXT:
+                               g_value_set_string (value, priv->text);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/atomtext.h b/src/atomtext.h
new file mode 100644 (file)
index 0000000..bbeb761
--- /dev/null
@@ -0,0 +1,71 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __ATOM_TEXT_H__
+#define __ATOM_TEXT_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "atomcommon.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_ATOM_TEXT                 (atom_text_get_type ())
+#define ATOM_TEXT(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ATOM_TEXT, AtomText))
+#define ATOM_TEXT_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ATOM_TEXT, AtomTextClass))
+#define IS_ATOM_TEXT(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ATOM_TEXT))
+#define IS_ATOM_TEXT_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ATOM_TEXT))
+#define ATOM_TEXT_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ATOM_TEXT, AtomTextClass))
+
+
+typedef struct _AtomText AtomText;
+typedef struct _AtomTextClass AtomTextClass;
+
+struct _AtomText
+       {
+               AtomCommon parent;
+       };
+
+struct _AtomTextClass
+       {
+               AtomCommonClass parent_class;
+       };
+
+typedef enum
+{
+       ATOM_TEXT_TEXT,
+       ATOM_TEXT_HTML,
+       ATOM_TEXT_XHTML
+} AtomTextType;
+
+GType atom_text_get_type (void) G_GNUC_CONST;
+
+AtomText *atom_text_new (AtomTextType type, const gchar *text);
+AtomText *atom_text_new_from_xml (xmlNode *xnode);
+
+void atom_text_get_xml (AtomText *atom_text, xmlNode *xnode);
+
+
+G_END_DECLS
+
+#endif /* __ATOM_TEXT_H__ */
diff --git a/src/gfeed.h b/src/gfeed.h
new file mode 100644 (file)
index 0000000..6400319
--- /dev/null
@@ -0,0 +1,41 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __GFEED_H__
+#define __GFEED_H__
+
+#include <rss.h>
+#include <rsscloud.h>
+#include <rssenclosure.h>
+#include <rssguid.h>
+#include <rssimage.h>
+#include <rsssource.h>
+#include <rsstextinput.h>
+
+#include <atom.h>
+#include <atomcategory.h>
+#include <atomentry.h>
+#include <atomgenerator.h>
+#include <atomlink.h>
+#include <atomperson.h>
+#include <atomcontent.h>
+
+#endif /* __GFEED_H__ */
diff --git a/src/rss.c b/src/rss.c
new file mode 100644 (file)
index 0000000..cf0208e
--- /dev/null
+++ b/src/rss.c
@@ -0,0 +1,293 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include "rss.h"
+
+enum
+{
+       PROP_0,
+       PROP_CHANNEL,
+};
+
+static void rss_class_init (RssClass *klass);
+static void rss_init (Rss *rss);
+
+static void rss_set_property (GObject *object,
+                              guint property_id,
+                              const GValue *value,
+                              GParamSpec *pspec);
+static void rss_get_property (GObject *object,
+                              guint property_id,
+                              GValue *value,
+                              GParamSpec *pspec);
+
+static Rss *parse_xml (xmlDoc *xdoc);
+
+#define RSS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RSS, RssPrivate))
+
+typedef struct _RssPrivate RssPrivate;
+struct _RssPrivate
+       {
+               RssChannel *channel;
+       };
+
+GType
+rss_get_type (void)
+{
+       static GType rss_type = 0;
+
+       if (!rss_type)
+               {
+                       static const GTypeInfo rss_info =
+                       {
+                               sizeof (RssClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) rss_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (Rss),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) rss_init,
+                               NULL
+                       };
+
+                       rss_type = g_type_register_static (G_TYPE_OBJECT, "Rss",
+                                                          &rss_info, 0);
+               }
+
+       return rss_type;
+}
+
+static void
+rss_class_init (RssClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (RssPrivate));
+
+       object_class->set_property = rss_set_property;
+       object_class->get_property = rss_get_property;
+
+       g_object_class_install_property (object_class, PROP_CHANNEL,
+                                        g_param_spec_object ("channel",
+                                                             "Channel",
+                                                             "The channel node",
+                                                             TYPE_RSSCHANNEL,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+rss_init (Rss *rss)
+{
+}
+
+/**
+ * rss_new:
+ *
+ * Returns: the newly created #Rss object.
+ */
+Rss
+*rss_new ()
+{
+       return RSS (g_object_new (rss_get_type (), NULL));
+}
+
+/**
+ * rss_new_from_file:
+ * @filename:
+ *
+ * Returns: the newly created #Rss object.
+ */
+Rss
+*rss_new_from_file (const gchar *filename)
+{
+       Rss *rss;
+
+       xmlDoc *xdoc = xmlParseFile (filename);
+
+       rss = parse_xml (xdoc);
+
+       return rss;
+}
+
+/**
+ * rss_new_from_buffer:
+ * @buffer: a pointer to an array of #gchar.
+ *
+ * Returns: the newly created #Rss object.
+ */
+Rss
+*rss_new_from_buffer (const gchar *buffer)
+{
+       Rss *rss;
+
+       xmlDoc *xdoc = xmlParseDoc (buffer);
+
+       rss = parse_xml (xdoc);
+
+       return rss;
+}
+
+/**
+ * rss_get_xml_doc:
+ * @rss: a #Rss object.
+ *
+ * Returns: the #xmlDoc correspondent to the entire rss file.
+ */
+xmlDoc
+*rss_get_xml_doc (Rss *rss)
+{
+       RssPrivate *priv = RSS_GET_PRIVATE (rss);
+
+       xmlDoc *xdoc = xmlNewDoc ((const xmlChar *)"1.0");
+       xmlNode *xroot = xmlNewNode (NULL, (const xmlChar *)"rss");
+
+  /* adding root element */
+  if (xroot == NULL) return NULL;
+
+  xmlSetProp (xroot, (const xmlChar *)"version", (const xmlChar *)"2.0");
+  xmlDocSetRootElement (xdoc, xroot);
+
+       if (priv->channel != NULL)
+               {
+                       xmlAddChild (xroot, rss_channel_get_xml (priv->channel));
+               }
+       else
+               {
+                       g_warning ("Node Â«channel» not present.");
+               }
+
+       return xdoc;
+}
+
+/**
+ * rss_save_file:
+ * @rss: a #Rss object.
+ * @filename:
+ *
+ */
+gboolean
+rss_save_file (Rss *rss, const gchar *filename)
+{
+       return (xmlSaveFileEnc (filename, rss_get_xml_doc (rss), "iso-8859-1") > -1);
+}
+
+static void
+rss_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       Rss *rss = RSS (object);
+
+       RssPrivate *priv = RSS_GET_PRIVATE (rss);
+
+       switch (property_id)
+               {
+                       case PROP_CHANNEL:
+                               if (g_value_get_object (value) != NULL)
+                                       {
+                                               priv->channel = (RssChannel *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+rss_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       Rss *rss = RSS (object);
+
+       RssPrivate *priv = RSS_GET_PRIVATE (rss);
+
+       switch (property_id)
+               {
+                       case PROP_CHANNEL:
+                               g_value_set_object (value, priv->channel);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static Rss
+*parse_xml (xmlDoc *xdoc)
+{
+       Rss *rss = rss_new ();
+
+       if (xdoc != NULL)
+               {
+                       xmlNode *cur = xmlDocGetRootElement (xdoc);
+                       if (cur != NULL)
+                               {
+                                       if (xmlStrcmp (cur->name, (const xmlChar *)"rss") == 0)
+                                               {
+                                                       if (xmlStrcmp (xmlGetProp (cur, (const xmlChar *)"version"), (const xmlChar *)"2.0") == 0)
+                                                               {
+                                                                       cur = cur->xmlChildrenNode;
+                                                                       if (cur != NULL)
+                                                                               {
+                                                                                       if (xmlStrcmp (cur->name, (const xmlChar *)"channel") == 0)
+                                                                                               {
+                                                                                                       RssChannel *rssc = rss_channel_new_from_xml (cur);
+                                                                                                       if (rssc != NULL)
+                                                                                                               {
+                                                                                                                       g_object_set (G_OBJECT (rss),
+                                                                                                                                     "channel", rssc,
+                                                                                                                                     NULL);
+                                                                                                               }
+                                                                                               }
+                                                                                       else
+                                                                                               {
+                                                                                                       g_critical ("The unique first element must be Â«channel»");
+                                                                                               }
+                                                                               }
+                                                                       else
+                                                                               {
+                                                                                       g_critical ("Empty rss document.");
+                                                                               }
+                                                               }
+                                                       else
+                                                               {
+                                                                       g_critical ("Wrong rss version.");
+                                                               }
+                                               }
+                                       else
+                                               {
+                                                       g_critical ("XML document is not a rss feed.");
+                                               }
+                               }
+                       else
+                               {
+                                       g_critical ("Empty document.");
+                               }
+               }
+
+       return rss;
+}
diff --git a/src/rss.h b/src/rss.h
new file mode 100644 (file)
index 0000000..a381b28
--- /dev/null
+++ b/src/rss.h
@@ -0,0 +1,67 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __RSS_H__
+#define __RSS_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+#include "rsschannel.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_RSS                 (rss_get_type ())
+#define RSS(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RSS, Rss))
+#define RSS_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RSS, RssClass))
+#define IS_RSS(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RSS))
+#define IS_RSS_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RSS))
+#define RSS_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RSS, RssClass))
+
+
+typedef struct _Rss Rss;
+typedef struct _RssClass RssClass;
+
+struct _Rss
+       {
+               GObject parent;
+       };
+
+struct _RssClass
+       {
+               GObjectClass parent_class;
+       };
+
+GType rss_get_type (void) G_GNUC_CONST;
+
+Rss *rss_new (void);
+Rss *rss_new_from_file (const gchar *filename);
+Rss *rss_new_from_buffer (const gchar *buffer);
+
+xmlDoc *rss_get_xml_doc (Rss *rss);
+gboolean rss_save_file (Rss *rss, const gchar *filename);
+
+
+G_END_DECLS
+
+#endif /* __RSS_H__ */
diff --git a/src/rsscategory.c b/src/rsscategory.c
new file mode 100644 (file)
index 0000000..0bdf99d
--- /dev/null
@@ -0,0 +1,242 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <time.h>
+
+#include <libxml/tree.h>
+
+#include "rsscategory.h"
+
+enum
+{
+       PROP_0,
+       PROP_LOCATION,
+       PROP_DOMAIN
+};
+
+static void rss_category_class_init (RssCategoryClass *klass);
+static void rss_category_init (RssCategory *rss);
+
+static void rss_category_set_property (GObject *object,
+                                       guint property_id,
+                                       const GValue *value,
+                                       GParamSpec *pspec);
+static void rss_category_get_property (GObject *object,
+                                       guint property_id,
+                                       GValue *value,
+                                       GParamSpec *pspec);
+
+#define RSSCATEGORY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RSSCATEGORY, RssCategoryPrivate))
+
+typedef struct _RssCategoryPrivate RssCategoryPrivate;
+struct _RssCategoryPrivate
+       {
+               gchar *location,
+                     *domain;
+       };
+
+GType
+rss_category_get_type (void)
+{
+       static GType rss_category_type = 0;
+
+       if (!rss_category_type)
+               {
+                       static const GTypeInfo rss_category_info =
+                       {
+                               sizeof (RssCategoryClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) rss_category_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (RssCategory),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) rss_category_init,
+                               NULL
+                       };
+
+                       rss_category_type = g_type_register_static (G_TYPE_OBJECT, "RssCategory",
+                                                                   &rss_category_info, 0);
+               }
+
+       return rss_category_type;
+}
+
+static void
+rss_category_class_init (RssCategoryClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (RssCategoryPrivate));
+
+       object_class->set_property = rss_category_set_property;
+       object_class->get_property = rss_category_get_property;
+
+       g_object_class_install_property (object_class, PROP_LOCATION,
+                                        g_param_spec_string ("location",
+                                                             "Location",
+                                                             "A forward-slash-separated string that identifies a hierarchic location in the indicated taxonomy.",
+                                                             "default",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_DOMAIN,
+                                        g_param_spec_string ("domain",
+                                                             "Domain",
+                                                             "A string that identifies a categorization taxonomy.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+rss_category_init (RssCategory *rss)
+{
+}
+
+/**
+ * rss_category_new:
+ * @location: A forward-slash-separated string that identifies a hierarchic location in the indicated taxonomy.
+ *
+ * Returns: the newly created #RssCategory object.
+ */
+RssCategory
+*rss_category_new (const gchar *location)
+{
+       g_return_val_if_fail (location != NULL, NULL);
+
+       gchar *_location = g_strstrip (g_strdup (location));
+
+       if (strcmp (_location, "") == 0)
+               {
+                       g_critical ("rss_category_new: location cannot be an empty string");
+                       return NULL;
+               }
+
+       RssCategory *rssc = RSSCATEGORY (g_object_new (rss_category_get_type (), NULL));
+
+       g_object_set (G_OBJECT (rssc),
+                     "location", _location,
+                     NULL);
+
+       return rssc;
+}
+
+/**
+ * rss_category_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ */
+RssCategory
+*rss_category_new_from_xml (xmlNode *xnode)
+{
+       g_return_val_if_fail (xnode != NULL, NULL);
+
+       RssCategory *rssc = rss_category_new ("location");
+       gboolean location = FALSE;
+
+       xmlChar *prop;
+
+       if ((prop = xmlGetProp (xnode, (const xmlChar *)"domain")) != NULL)
+               {
+                       g_object_set (G_OBJECT (rssc),
+                                     "domain", (gchar *)prop,
+                                     NULL);
+               }
+
+       gchar *text = (gchar *)xmlNodeGetContent (xnode);
+       if (strcmp (g_strstrip (text), "") != 0)
+               {
+                       location = TRUE;
+                       g_object_set (G_OBJECT (rssc),
+                                     "location", text,
+                                     NULL);
+               }
+
+       return (!location ? NULL : rssc);
+}
+
+/**
+ * rss_category_get_xml:
+ * @rss_category: a #RssCategory object
+ *
+ * Returns: the #xmlNode correspondent to the item.
+ */
+xmlNode
+*rss_category_get_xml (RssCategory *rss_category)
+{
+       RssCategoryPrivate *priv = RSSCATEGORY_GET_PRIVATE (rss_category);
+
+       xmlNode *xnode = xmlNewNode (NULL, (const xmlChar *)"category");
+
+       xmlAddChild (xnode, xmlNewText ((const xmlChar *)priv->location));
+
+       if (strcmp (priv->domain, "") != 0)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"domain", (const xmlChar *)priv->domain);
+               }
+
+       return xnode;
+}
+
+static void
+rss_category_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       RssCategory *rssc = RSSCATEGORY (object);
+
+       RssCategoryPrivate *priv = RSSCATEGORY_GET_PRIVATE (rssc);
+
+       switch (property_id)
+               {
+                       case PROP_LOCATION:
+                               priv->location = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_DOMAIN:
+                               priv->domain = g_strdup (g_value_get_string (value));
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+rss_category_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       RssCategory *rssc = RSSCATEGORY (object);
+
+       RssCategoryPrivate *priv = RSSCATEGORY_GET_PRIVATE (rssc);
+
+       switch (property_id)
+               {
+                       case PROP_LOCATION:
+                               g_value_set_string (value, priv->location);
+                               break;
+
+                       case PROP_DOMAIN:
+                               g_value_set_string (value, priv->domain);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/rsscategory.h b/src/rsscategory.h
new file mode 100644 (file)
index 0000000..abd3b00
--- /dev/null
@@ -0,0 +1,63 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __RSSCATEGORY_H__
+#define __RSSCATEGORY_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+G_BEGIN_DECLS
+
+
+#define TYPE_RSSCATEGORY                 (rss_category_get_type ())
+#define RSSCATEGORY(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RSSCATEGORY, RssCategory))
+#define RSSCATEGORY_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RSSCATEGORY, RssCategoryClass))
+#define IS_RSSCATEGORY(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RSSCATEGORY))
+#define IS_RSSCATEGORY_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RSSCATEGORY))
+#define RSSCATEGORY_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RSSCATEGORY, RssCategoryClass))
+
+
+typedef struct _RssCategory RssCategory;
+typedef struct _RssCategoryClass RssCategoryClass;
+
+struct _RssCategory
+       {
+               GObject parent;
+       };
+
+struct _RssCategoryClass
+       {
+               GObjectClass parent_class;
+       };
+
+GType rss_category_get_type (void) G_GNUC_CONST;
+
+RssCategory *rss_category_new (const gchar *location);
+RssCategory *rss_category_new_from_xml (xmlNode *xnode);
+
+xmlNode *rss_category_get_xml (RssCategory *rss_category);
+
+
+G_END_DECLS
+
+#endif /* __RSSCATEGORY_H__ */
diff --git a/src/rsschannel.c b/src/rsschannel.c
new file mode 100644 (file)
index 0000000..6f762fa
--- /dev/null
@@ -0,0 +1,1095 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <time.h>
+#include <libxml/tree.h>
+
+#include "rsschannel.h"
+#include "rssimage.h"
+#include "rsstextinput.h"
+#include "rsscloud.h"
+
+enum
+{
+       PROP_0,
+       PROP_TITLE,
+       PROP_LINK,
+       PROP_DESCRIPTION,
+       PROP_LANGUAGE,
+       PROP_COPYRIGHT,
+       PROP_MANAGING_EDITOR,
+       PROP_WEBMASTER,
+       PROP_PUB_DATE,
+       PROP_LAST_BUILD_DATE,
+       PROP_GENERATOR,
+       PROP_DOCS,
+       PROP_CLOUD,
+       PROP_TTL,
+       PROP_IMAGE,
+       PROP_TEXT_INPUT,
+       PROP_SKIP_HOURS,
+       PROP_SKIP_DAYS
+};
+
+static void rss_channel_class_init (RssChannelClass *klass);
+static void rss_channel_init (RssChannel *rss);
+
+static void rss_channel_set_property (GObject *object,
+                                      guint property_id,
+                                      const GValue *value,
+                                      GParamSpec *pspec);
+static void rss_channel_get_property (GObject *object,
+                                      guint property_id,
+                                      GValue *value,
+                                      GParamSpec *pspec);
+
+#define RSSCHANNEL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RSSCHANNEL, RssChannelPrivate))
+
+typedef struct _RssChannelPrivate RssChannelPrivate;
+struct _RssChannelPrivate
+       {
+               gchar *title,
+                     *link,
+                     *description,
+                     *language,
+                     *copyright,
+                     *managingEditor,
+                     *webMaster,
+                     *generator,
+                     *docs;
+               struct tm *pubDate,
+                         *lastBuildDate;
+               guint ttl,
+                     skipHours,
+                     skipDays;
+               RssCloud *cloud;
+               RssImage *image;
+               RssTextInput *textInput;
+
+               GList *categories, *items;
+       };
+
+GType
+rss_channel_get_type (void)
+{
+       static GType rss_channel_type = 0;
+
+       if (!rss_channel_type)
+               {
+                       static const GTypeInfo rss_channel_info =
+                       {
+                               sizeof (RssChannelClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) rss_channel_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (RssChannel),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) rss_channel_init,
+                               NULL
+                       };
+
+                       rss_channel_type = g_type_register_static (G_TYPE_OBJECT, "RssChannel",
+                                                                  &rss_channel_info, 0);
+               }
+
+       return rss_channel_type;
+}
+
+static void
+rss_channel_class_init (RssChannelClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (RssChannelPrivate));
+
+       object_class->set_property = rss_channel_set_property;
+       object_class->get_property = rss_channel_get_property;
+
+       g_object_class_install_property (object_class, PROP_TITLE,
+                                        g_param_spec_string ("title",
+                                                             "Title",
+                                                             "The name of the channel",
+                                                             "default",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_LINK,
+                                        g_param_spec_string ("link",
+                                                             "Link",
+                                                             "The URL to the HTML website corresponding to the channel",
+                                                             "default",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_DESCRIPTION,
+                                        g_param_spec_string ("description",
+                                                             "Description",
+                                                             "Phrase or sentence describing the channel",
+                                                             "default",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_LANGUAGE,
+                                        g_param_spec_string ("language",
+                                                             "Language",
+                                                             "The language the channel is written in",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_COPYRIGHT,
+                                        g_param_spec_string ("copyright",
+                                                             "Copyright",
+                                                             "Copyright notice for content in the channel",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_MANAGING_EDITOR,
+                                        g_param_spec_string ("managing-editor",
+                                                             "Managing editor",
+                                                             "Email address for person responsible for editorial content",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_WEBMASTER,
+                                        g_param_spec_string ("webmaster",
+                                                             "Webmaster",
+                                                             "Email address for person responsible for technical issues relating to channel",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_PUB_DATE,
+                                        g_param_spec_pointer ("pub-date",
+                                                              "Publication date",
+                                                              "The publication date for the content in the channel",
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_LAST_BUILD_DATE,
+                                        g_param_spec_pointer ("last-build-date",
+                                                              "Last build date",
+                                                              "The last time the content of the channel changed",
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_GENERATOR,
+                                        g_param_spec_string ("generator",
+                                                             "Generator",
+                                                             "A string indicating the program used to generate the channel",
+                                                             "<a href=\"http://libgfeed.sourceforge.net\">libgfeed v0.0.1</a>",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_DOCS,
+                                        g_param_spec_string ("docs",
+                                                             "Docs",
+                                                             "A URL that points to the documentation for the format used in the RSS file",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_CLOUD,
+                                        g_param_spec_object ("cloud",
+                                                             "Cloud",
+                                                             "Allows processes to register with a cloud to be notified of updates to the channel, implementing a lightweight publish-subscribe protocol for RSS feeds.",
+                                                             TYPE_RSSCLOUD,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_TTL,
+                                        g_param_spec_uint ("ttl",
+                                                           "TTL",
+                                                           "Time To Live",
+                                                           0,
+                                                           UINT_MAX,
+                                                           0,
+                                                           G_PARAM_READWRITE));
+       g_object_class_install_property (object_class, PROP_IMAGE,
+                                        g_param_spec_object ("image",
+                                                             "Image",
+                                                             "Specifies a GIF, JPEG or PNG image that can be displayed with the channel.",
+                                                             TYPE_RSSIMAGE,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_TEXT_INPUT,
+                                        g_param_spec_object ("text-input",
+                                                             "Text Input",
+                                                             "Specifies a text input box that can be displayed with the channel.",
+                                                             TYPE_RSSTEXTINPUT,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_SKIP_HOURS,
+                                        g_param_spec_uint ("skip-hours",
+                                                           "Skip hours",
+                                                           "A hint for aggregators telling them which hours they can skip",
+                                                           0,
+                                                           16777215,
+                                                           0,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_SKIP_DAYS,
+                                        g_param_spec_uint ("skip-days",
+                                                           "Skip days",
+                                                           "A hint for aggregators telling them which days they can skip",
+                                                           0,
+                                                           127,
+                                                           0,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+rss_channel_init (RssChannel *rss_channel)
+{
+       RssChannelPrivate *priv = RSSCHANNEL_GET_PRIVATE (rss_channel);
+
+       priv->ttl = 0;
+}
+
+/**
+ * rss_channel_new:
+ * @title: The name of the channel. It's how people refer to your service.
+ * @link: The URL to the HTML website corresponding to the channel.
+ * @description: Phrase or sentence describing the channel.
+ *
+ * Returns: the newly created #RssChannel object.
+ */
+RssChannel
+*rss_channel_new (const gchar *title, const gchar *link, const gchar *description)
+{
+       g_return_val_if_fail (title != NULL, NULL);
+       g_return_val_if_fail (link != NULL, NULL);
+       g_return_val_if_fail (description != NULL, NULL);
+
+       gchar *_title = g_strstrip (g_strdup (title)),
+             *_link = g_strstrip (g_strdup (link)),
+             *_description = g_strstrip (g_strdup (description));
+
+       if (strcmp (_title, "") == 0)
+               {
+                       g_critical ("rss_channel_new: title cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_link, "") == 0)
+               {
+                       g_critical ("rss_channel_new: link cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_description, "") == 0)
+               {
+                       g_critical ("rss_channel_new: description cannot be an empty string");
+                       return NULL;
+               }
+
+       RssChannel *rssc = RSSCHANNEL (g_object_new (rss_channel_get_type (), NULL));
+
+       g_object_set (G_OBJECT (rssc),
+                     "title", _title,
+                     "link", _link,
+                     "description", _description,
+                     NULL);
+
+       return rssc;
+}
+
+/**
+ * rss_channel_new_from_xml:
+ * @xnode: a #xmlNode to parse.
+ *
+ * Returns: the newly created #RssChannel object.
+ */
+RssChannel
+*rss_channel_new_from_xml (xmlNode *xnode)
+{
+       /* creating a temporary rss_channel */
+       RssChannel *rssc = rss_channel_new ("title", "link", "description");
+       gboolean title = FALSE, link = FALSE, description = FALSE;
+
+       xmlNode *cur = xnode->xmlChildrenNode;
+       while (cur != NULL)
+               {
+                       if (xmlStrcmp (cur->name, (const xmlChar *)"title") == 0)
+                               {
+                                       title = TRUE;
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "title", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"link") == 0)
+                               {
+                                       link = TRUE;
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "link", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"description") == 0)
+                               {
+                                       description = TRUE;
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "description", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"language") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "language", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"copyright") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "copyright", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"managingEditor") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "managing-editor", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"webmaster") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "webmaster", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"pubDate") == 0)
+                               {
+                                       struct tm tm;
+                                       gchar *ret, *text = (gchar *)xmlNodeGetContent (cur);
+                                       ret = (gchar *)strptime (text, "%a, %d %b %Y %T GMT", &tm);
+                                       if (ret != NULL)
+                                               {
+                                                       g_object_set (G_OBJECT (rssc),
+                                                                     "pub-date", &tm,
+                                                                     NULL);
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"lastBuildDate") == 0)
+                               {
+                                       struct tm tm;
+                                       gchar *ret, *text = (gchar *)xmlNodeGetContent (cur);
+                                       ret = (gchar *)strptime (text, "%a, %d %b %Y %T GMT", &tm);
+                                       if (ret != NULL)
+                                               {
+                                                       g_object_set (G_OBJECT (rssc),
+                                                                     "last-build-date", &tm,
+                                                                     NULL);
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"category") == 0)
+                               {
+                                       rss_channel_add_category (rssc, rss_category_new_from_xml (cur));
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"generator") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "generator", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"docs") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "docs", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"cloud") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "cloud", rss_cloud_new_from_xml (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"ttl") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "ttl", atol ((char *)xmlNodeGetContent (cur)),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"image") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "image", rss_image_new_from_xml (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"textInput") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssc),
+                                                     "text-input", rss_text_input_new_from_xml (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"skipHours") == 0)
+                               {
+                                       xmlNode *xhours = cur->xmlChildrenNode;
+                                       guint hours = 0;
+                                       while (xhours != NULL)
+                                               {
+                                                       if (xmlStrcmp (xhours->name, (const xmlChar *)"hour") == 0)
+                                                               {
+                                                                       if (atol ((char *)xmlNodeGetContent (xhours)) == 0)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_0;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 1)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_1;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 2)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_2;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 3)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_3;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 4)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_4;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 5)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_5;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 6)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_6;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 7)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_7;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 8)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_8;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 9)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_9;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 10)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_10;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 11)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_11;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 12)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_12;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 13)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_13;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 14)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_14;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 15)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_15;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 16)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_16;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 17)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_17;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 18)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_18;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 19)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_19;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 20)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_20;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 21)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_21;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 22)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_22;
+                                                                               }
+                                                                       else if (atol ((char *)xmlNodeGetContent (xhours)) == 23)
+                                                                               {
+                                                                                       hours |= RSSCHANNEL_HOUR_23;
+                                                                               }
+                                                               }
+                                               
+                                                       xhours = xhours->next;
+                                               }
+
+                                       if (hours > 0)
+                                               {
+                                                       g_object_set (G_OBJECT (rssc),
+                                                                     "skip-hours", hours,
+                                                                     NULL);
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"skipDays") == 0)
+                               {
+                                       xmlNode *xdays = cur->xmlChildrenNode;
+                                       guint days = 0;
+                                       while (xdays != NULL)
+                                               {
+                                                       if (xmlStrcmp (xdays->name, (const xmlChar *)"day") == 0)
+                                                               {
+                                                                       if (xmlStrcasestr (xmlNodeGetContent (xdays), (xmlChar *)"Monday") != NULL)
+                                                                               {
+                                                                                       days |= RSSCHANNEL_DAY_MONDAY;
+                                                                               }
+                                                                       else if (xmlStrcasestr (xmlNodeGetContent (xdays), (xmlChar *)"Tuesday") != NULL)
+                                                                               {
+                                                                                       days |= RSSCHANNEL_DAY_TUESDAY;
+                                                                               }
+                                                                       else if (xmlStrcasestr (xmlNodeGetContent (xdays), (xmlChar *)"Wednesday") != NULL)
+                                                                               {
+                                                                                       days |= RSSCHANNEL_DAY_WEDNESDAY;
+                                                                               }
+                                                                       else if (xmlStrcasestr (xmlNodeGetContent (xdays), (xmlChar *)"Thursday") != NULL)
+                                                                               {
+                                                                                       days |= RSSCHANNEL_DAY_THURSDAY;
+                                                                               }
+                                                                       else if (xmlStrcasestr (xmlNodeGetContent (xdays), (xmlChar *)"Friday") != NULL)
+                                                                               {
+                                                                                       days |= RSSCHANNEL_DAY_FRIDAY;
+                                                                               }
+                                                                       else if (xmlStrcasestr (xmlNodeGetContent (xdays), (xmlChar *)"Saturday") != NULL)
+                                                                               {
+                                                                                       days |= RSSCHANNEL_DAY_SATURDAY;
+                                                                               }
+                                                                       else if (xmlStrcasestr (xmlNodeGetContent (xdays), (xmlChar *)"Sunday") != NULL)
+                                                                               {
+                                                                                       days |= RSSCHANNEL_DAY_SUNDAY;
+                                                                               }
+                                                               }
+
+                                                       xdays = xdays->next;
+                                               }
+
+                                       if (days > 0)
+                                               {
+                                                       g_object_set (G_OBJECT (rssc),
+                                                                     "skip-days", days,
+                                                                     NULL);
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"item") == 0)
+                               {
+                                       rss_channel_add_item (rssc, rss_channel_item_new_from_xml (cur));
+                               }
+
+                       cur = cur->next;
+               }
+
+       return (!title || !link || !description ? NULL : rssc);
+}
+
+/**
+ * rss_channel_add_category:
+ * @rss_channel: a #RssChannel object.
+ * @rss_category: a #RssCategory object.
+ *
+ */
+gboolean
+rss_channel_add_category (RssChannel *rss_channel, RssCategory *rss_category)
+{
+       g_return_val_if_fail (rss_category != NULL, FALSE);
+
+       RssChannelPrivate *priv = RSSCHANNEL_GET_PRIVATE (rss_channel);
+
+       priv->categories = g_list_append (priv->categories, rss_category);
+
+       return TRUE;
+}
+
+/**
+ * rss_channel_get_categories:
+ * @rss_channel: a #RssChannel object.
+ *
+ */
+GList
+*rss_channel_get_categories (RssChannel *rss_channel)
+{
+       RssChannelPrivate *priv = RSSCHANNEL_GET_PRIVATE (rss_channel);
+
+       return priv->categories;
+}
+
+/**
+ * rss_channel_add_item:
+ * @rss_channel: a #RssChannel object.
+ * @rss_channel_item: a #RssChannelItem object.
+ *
+ */
+gboolean
+rss_channel_add_item (RssChannel *rss_channel, RssChannelItem *rss_channel_item)
+{
+       RssChannelPrivate *priv = RSSCHANNEL_GET_PRIVATE (rss_channel);
+
+       priv->items = g_list_append (priv->items, rss_channel_item);
+
+       return TRUE;
+}
+
+/**
+ * rss_channel_remove_item:
+ * @rss_channel: a #RssChannel object.
+ * @rss_channel_item: a #RssChannelItem object.
+ *
+ */
+gboolean
+rss_channel_remove_item (RssChannel *rss_channel, RssChannelItem *rss_channel_item)
+{
+       RssChannelPrivate *priv = RSSCHANNEL_GET_PRIVATE (rss_channel);
+
+       priv->items = g_list_remove (priv->items, (gconstpointer)rss_channel_item);
+
+       return TRUE;
+}
+
+/**
+ * rss_channel_get_xml:
+ * @rss_channel: a #RssChannel object.
+ *
+ * Returns: the #xmlNode correspondent to the channel and its items.
+ */
+xmlNode
+*rss_channel_get_xml (RssChannel *rss_channel)
+{
+       char pd[256];
+       GList *categories, *items;
+       RssChannelPrivate *priv = RSSCHANNEL_GET_PRIVATE (rss_channel);
+
+       xmlNode *xnode = xmlNewNode (NULL, (const xmlChar *)"channel");
+
+       xmlNewTextChild (xnode, NULL, (const xmlChar *)"title", (const xmlChar *)priv->title);
+       xmlNewTextChild (xnode, NULL, (const xmlChar *)"link", (const xmlChar *)priv->link);
+       xmlNewTextChild (xnode, NULL, (const xmlChar *)"description", (const xmlChar *)priv->description);
+
+       if (strcmp (priv->language, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"language", (const xmlChar *)priv->language);
+               }
+       if (strcmp (priv->copyright, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"copyright", (const xmlChar *)priv->copyright);
+               }
+       if (strcmp (priv->managingEditor, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"managingEditor", (const xmlChar *)priv->managingEditor);
+               }
+       if (strcmp (priv->webMaster, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"webMaster", (const xmlChar *)priv->webMaster);
+               }
+
+       if (priv->pubDate != NULL)
+               {
+                       strftime (pd, 256, "%a, %d %b %Y %T GMT", (const struct tm *)priv->pubDate);
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"pubDate", (const xmlChar *)pd);
+               }
+       if (priv->lastBuildDate != NULL)
+               {
+                       strftime (pd, 256, "%a, %d %b %Y %T GMT", (const struct tm *)priv->lastBuildDate);
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"lastBuildDate", (const xmlChar *)pd);
+               }
+
+       categories = priv->categories;
+       while (categories != NULL)
+               {
+                       xmlAddChild (xnode, rss_category_get_xml ((RssCategory *)categories->data));
+
+                       categories = g_list_next (categories);
+               }
+
+       if (strcmp (priv->generator, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"generator", (const xmlChar *)priv->generator);
+               }
+       if (strcmp (priv->docs, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"docs", (const xmlChar *)priv->docs);
+               }
+
+       if (priv->cloud != NULL)
+               {
+                       xmlAddChild (xnode, rss_cloud_get_xml (priv->cloud));
+               }
+
+       if (priv->ttl > 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"ttl", (const xmlChar *)g_strdup_printf ("%d", priv->ttl));
+               }
+
+       if (priv->image != NULL)
+               {
+                       xmlAddChild (xnode, rss_image_get_xml (priv->image));
+               }
+
+       if (priv->textInput!= NULL)
+               {
+                       xmlAddChild (xnode, rss_text_input_get_xml (priv->textInput));
+               }
+
+       if (priv->skipHours > 0)
+               {
+                       xmlNode *xnodeh = xmlNewNode (NULL, (const xmlChar *)"skipHours");
+                       if (priv->skipHours & RSSCHANNEL_HOUR_0)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"0");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_1)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"1");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_2)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"2");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_3)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"3");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_4)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"4");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_5)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"5");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_6)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"6");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_7)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"7");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_8)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"8");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_9)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"9");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_10)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"10");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_11)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"11");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_12)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"12");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_13)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"13");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_14)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"14");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_15)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"15");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_16)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"16");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_17)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"17");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_18)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"18");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_19)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"19");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_20)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"20");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_21)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"21");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_22)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"22");
+                               }
+                       if (priv->skipHours & RSSCHANNEL_HOUR_23)
+                               {
+                                       xmlNewTextChild (xnodeh, NULL, (const xmlChar *)"hour", (const xmlChar *)"23");
+                               }
+
+                       xmlAddChild (xnode, xnodeh);
+               }
+
+       if (priv->skipDays > 0)
+               {
+                       xmlNode *xnoded = xmlNewNode (NULL, (const xmlChar *)"skipDays");
+                       if (priv->skipDays & RSSCHANNEL_DAY_MONDAY)
+                               {
+                                       xmlNewTextChild (xnoded, NULL, (const xmlChar *)"day", (const xmlChar *)"Monday");
+                               }
+                       if (priv->skipDays & RSSCHANNEL_DAY_TUESDAY)
+                               {
+                                       xmlNewTextChild (xnoded, NULL, (const xmlChar *)"day", (const xmlChar *)"Tuesday");
+                               }
+                       if (priv->skipDays & RSSCHANNEL_DAY_WEDNESDAY)
+                               {
+                                       xmlNewTextChild (xnoded, NULL, (const xmlChar *)"day", (const xmlChar *)"Wednesday");
+                               }
+                       if (priv->skipDays & RSSCHANNEL_DAY_THURSDAY)
+                               {
+                                       xmlNewTextChild (xnoded, NULL, (const xmlChar *)"day", (const xmlChar *)"Thursday");
+                               }
+                       if (priv->skipDays & RSSCHANNEL_DAY_FRIDAY)
+                               {
+                                       xmlNewTextChild (xnoded, NULL, (const xmlChar *)"day", (const xmlChar *)"Friday");
+                               }
+                       if (priv->skipDays & RSSCHANNEL_DAY_SATURDAY)
+                               {
+                                       xmlNewTextChild (xnoded, NULL, (const xmlChar *)"day", (const xmlChar *)"Saturday");
+                               }
+                       if (priv->skipDays & RSSCHANNEL_DAY_SUNDAY)
+                               {
+                                       xmlNewTextChild (xnoded, NULL, (const xmlChar *)"day", (const xmlChar *)"Sunday");
+                               }
+
+                       xmlAddChild (xnode, xnoded);
+               }
+
+       items = priv->items;
+       while (items != NULL)
+               {
+                       xmlAddChild (xnode, rss_channel_item_get_xml ((RssChannelItem *)items->data));
+
+                       items = g_list_next (items);
+               }
+
+       return xnode;
+}
+
+static void
+rss_channel_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       RssChannel *rssc = RSSCHANNEL (object);
+
+       RssChannelPrivate *priv = RSSCHANNEL_GET_PRIVATE (rssc);
+
+       switch (property_id)
+               {
+                       case PROP_TITLE:
+                               {
+                                       gchar *prop = g_strdup (g_value_get_string (value));
+                                       if (strcmp (g_strstrip (prop), "") == 0)
+                                               {
+                                                       g_critical ("rss_channel_set_property: title cannot be an empty string");
+                                               }
+                                       else
+                                               {
+                                                       priv->title = prop;
+                                               }
+                               }
+                               break;
+
+                       case PROP_LINK:
+                               {
+                                       gchar *prop = g_strdup (g_value_get_string (value));
+                                       if (strcmp (g_strstrip (prop), "") == 0)
+                                               {
+                                                       g_critical ("rss_channel_set_property: link cannot be an empty string");
+                                               }
+                                       else
+                                               {
+                                                       priv->link = prop;
+                                               }
+                               }
+                               break;
+
+                       case PROP_DESCRIPTION:
+                               {
+                                       gchar *prop = g_strdup (g_value_get_string (value));
+                                       if (strcmp (g_strstrip (prop), "") == 0)
+                                               {
+                                                       g_critical ("rss_channel_set_property: description cannot be an empty string");
+                                               }
+                                       else
+                                               {
+                                                       priv->description = prop;
+                                               }
+                               }
+                               break;
+
+                       case PROP_LANGUAGE:
+                               priv->language = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_COPYRIGHT:
+                               priv->copyright = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_MANAGING_EDITOR:
+                               priv->managingEditor = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_WEBMASTER:
+                               priv->webMaster = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_PUB_DATE:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->pubDate = g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (struct tm));
+                                       }
+                               break;
+
+                       case PROP_LAST_BUILD_DATE:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->lastBuildDate = g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (struct tm));
+                                       }
+                               break;
+
+                       case PROP_GENERATOR:
+                               priv->generator = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_DOCS:
+                               priv->docs = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_CLOUD:
+                               if (g_value_get_object (value) != NULL)
+                                       {
+                                               priv->cloud = (RssCloud *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_TTL:
+                               priv->ttl = g_value_get_uint (value);
+                               break;
+
+                       case PROP_IMAGE:
+                               if (g_value_get_object (value) != NULL)
+                                       {
+                                               priv->image = (RssImage *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_TEXT_INPUT:
+                               if (g_value_get_object (value) != NULL)
+                                       {
+                                               priv->textInput = (RssTextInput *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_SKIP_HOURS:
+                               priv->skipHours = g_value_get_uint (value);
+                               break;
+
+                       case PROP_SKIP_DAYS:
+                               priv->skipDays = g_value_get_uint (value);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+rss_channel_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       RssChannel *rssc = RSSCHANNEL (object);
+
+       RssChannelPrivate *priv = RSSCHANNEL_GET_PRIVATE (rssc);
+
+       switch (property_id)
+               {
+                       case PROP_TITLE:
+                               g_value_set_string (value, priv->title);
+                               break;
+
+                       case PROP_LINK:
+                               g_value_set_string (value, priv->link);
+                               break;
+
+                       case PROP_DESCRIPTION:
+                               g_value_set_string (value, priv->description);
+                               break;
+
+                       case PROP_LANGUAGE:
+                               g_value_set_string (value, priv->language);
+                               break;
+
+                       case PROP_COPYRIGHT:
+                               g_value_set_string (value, priv->copyright);
+                               break;
+
+                       case PROP_MANAGING_EDITOR:
+                               g_value_set_string (value, priv->managingEditor);
+                               break;
+
+                       case PROP_WEBMASTER:
+                               g_value_set_string (value, priv->webMaster);
+                               break;
+
+                       case PROP_PUB_DATE:
+                               g_value_set_pointer (value, priv->pubDate);
+                               break;
+
+                       case PROP_LAST_BUILD_DATE:
+                               g_value_set_pointer (value, priv->lastBuildDate);
+                               break;
+
+                       case PROP_GENERATOR:
+                               g_value_set_string (value, priv->generator);
+                               break;
+
+                       case PROP_DOCS:
+                               g_value_set_string (value, priv->docs);
+                               break;
+
+                       case PROP_CLOUD:
+                               g_value_set_object (value, priv->cloud);
+                               break;
+
+                       case PROP_TTL:
+                               g_value_set_uint (value, priv->ttl);
+                               break;
+
+                       case PROP_IMAGE:
+                               g_value_set_object (value, priv->image);
+                               break;
+
+                       case PROP_TEXT_INPUT:
+                               g_value_set_object (value, priv->textInput);
+                               break;
+
+                       case PROP_SKIP_HOURS:
+                               g_value_set_uint (value, priv->skipHours);
+                               break;
+
+                       case PROP_SKIP_DAYS:
+                               g_value_set_uint (value, priv->skipDays);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/rsschannel.h b/src/rsschannel.h
new file mode 100644 (file)
index 0000000..f70af3e
--- /dev/null
@@ -0,0 +1,105 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __RSSCHANNEL_H__
+#define __RSSCHANNEL_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+#include "rsscategory.h"
+#include "rsschannelitem.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_RSSCHANNEL                 (rss_channel_get_type ())
+#define RSSCHANNEL(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RSSCHANNEL, RssChannel))
+#define RSSCHANNEL_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RSSCHANNEL, RssChannelClass))
+#define IS_RSSCHANNEL(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RSSCHANNEL))
+#define IS_RSSCHANNEL_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RSSCHANNEL))
+#define RSSCHANNEL_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RSSCHANNEL, RssChannelClass))
+
+
+#define RSSCHANNEL_DAY_MONDAY     1 << 0
+#define RSSCHANNEL_DAY_TUESDAY    1 << 1
+#define RSSCHANNEL_DAY_WEDNESDAY  1 << 2
+#define RSSCHANNEL_DAY_THURSDAY   1 << 3
+#define RSSCHANNEL_DAY_FRIDAY     1 << 4
+#define RSSCHANNEL_DAY_SATURDAY   1 << 5
+#define RSSCHANNEL_DAY_SUNDAY     1 << 6
+
+#define RSSCHANNEL_HOUR_0   1 << 0
+#define RSSCHANNEL_HOUR_1   1 << 1
+#define RSSCHANNEL_HOUR_2   1 << 2
+#define RSSCHANNEL_HOUR_3   1 << 3
+#define RSSCHANNEL_HOUR_4   1 << 4
+#define RSSCHANNEL_HOUR_5   1 << 5
+#define RSSCHANNEL_HOUR_6   1 << 6
+#define RSSCHANNEL_HOUR_7   1 << 7
+#define RSSCHANNEL_HOUR_8   1 << 8
+#define RSSCHANNEL_HOUR_9   1 << 9
+#define RSSCHANNEL_HOUR_10  1 << 10
+#define RSSCHANNEL_HOUR_11  1 << 11
+#define RSSCHANNEL_HOUR_12  1 << 12
+#define RSSCHANNEL_HOUR_13  1 << 13
+#define RSSCHANNEL_HOUR_14  1 << 14
+#define RSSCHANNEL_HOUR_15  1 << 15
+#define RSSCHANNEL_HOUR_16  1 << 16
+#define RSSCHANNEL_HOUR_17  1 << 17
+#define RSSCHANNEL_HOUR_18  1 << 18
+#define RSSCHANNEL_HOUR_19  1 << 19
+#define RSSCHANNEL_HOUR_20  1 << 20
+#define RSSCHANNEL_HOUR_21  1 << 21
+#define RSSCHANNEL_HOUR_22  1 << 22
+#define RSSCHANNEL_HOUR_23  1 << 23
+
+typedef struct _RssChannel RssChannel;
+typedef struct _RssChannelClass RssChannelClass;
+
+struct _RssChannel
+       {
+               GObject parent;
+       };
+
+struct _RssChannelClass
+       {
+               GObjectClass parent_class;
+       };
+
+GType rss_channel_get_type (void) G_GNUC_CONST;
+
+RssChannel *rss_channel_new (const gchar *title, const gchar *link, const gchar *description);
+RssChannel *rss_channel_new_from_xml (xmlNode *xnode);
+
+gboolean rss_channel_add_category (RssChannel *rss_channel, RssCategory *rss_category);
+GList *rss_channel_get_categories (RssChannel *rss_channel);
+
+gboolean rss_channel_add_item (RssChannel *rss_channel, RssChannelItem *rss_channel_item);
+gboolean rss_channel_remove_item (RssChannel *rss_channel, RssChannelItem *rss_channel_item);
+
+xmlNode *rss_channel_get_xml (RssChannel *rss_channel);
+
+
+G_END_DECLS
+
+#endif /* __RSSCHANNEL_H__ */
diff --git a/src/rsschannelitem.c b/src/rsschannelitem.c
new file mode 100644 (file)
index 0000000..4b69553
--- /dev/null
@@ -0,0 +1,502 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <time.h>
+
+#include <libxml/tree.h>
+
+#include "rsschannelitem.h"
+#include "rssenclosure.h"
+#include "rssguid.h"
+#include "rsssource.h"
+
+enum
+{
+       PROP_0,
+       PROP_TITLE,
+       PROP_LINK,
+       PROP_DESCRIPTION,
+       PROP_AUTHOR,
+       PROP_COMMENTS,
+       PROP_ENCLOSURE,
+       PROP_GUID,
+       PROP_PUB_DATE,
+       PROP_SOURCE
+};
+
+static void rss_channel_item_class_init (RssChannelItemClass *klass);
+static void rss_channel_item_init (RssChannelItem *rss);
+
+static void rss_channel_item_set_property (GObject *object,
+                                           guint property_id,
+                                           const GValue *value,
+                                           GParamSpec *pspec);
+static void rss_channel_item_get_property (GObject *object,
+                                           guint property_id,
+                                           GValue *value,
+                                           GParamSpec *pspec);
+
+#define RSSCHANNELITEM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RSSCHANNELITEM, RssChannelItemPrivate))
+
+typedef struct _RssChannelItemPrivate RssChannelItemPrivate;
+struct _RssChannelItemPrivate
+       {
+               gchar *title,
+                     *link,
+                     *description,
+                     *author,
+                     *category,
+                     *comments;
+               RssEnclosure *enclosure;
+               RssGuid *guid;
+               struct tm *pubDate;
+               GList *categories;
+               RssSource *source;
+       };
+
+GType
+rss_channel_item_get_type (void)
+{
+       static GType rss_channel_item_type = 0;
+
+       if (!rss_channel_item_type)
+               {
+                       static const GTypeInfo rss_channel_item_info =
+                       {
+                               sizeof (RssChannelItemClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) rss_channel_item_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (RssChannelItem),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) rss_channel_item_init,
+                               NULL
+                       };
+
+                       rss_channel_item_type = g_type_register_static (G_TYPE_OBJECT, "RssChannelItem",
+                                                                       &rss_channel_item_info, 0);
+               }
+
+       return rss_channel_item_type;
+}
+
+static void
+rss_channel_item_class_init (RssChannelItemClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (RssChannelItemPrivate));
+
+       object_class->set_property = rss_channel_item_set_property;
+       object_class->get_property = rss_channel_item_get_property;
+
+       g_object_class_install_property (object_class, PROP_TITLE,
+                                        g_param_spec_string ("title",
+                                                             "Title",
+                                                             "The title of the item.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_LINK,
+                                        g_param_spec_string ("link",
+                                                             "Link",
+                                                             "The URL of the item.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_DESCRIPTION,
+                                        g_param_spec_string ("description",
+                                                             "Description",
+                                                             "The item synopsis.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_AUTHOR,
+                                        g_param_spec_string ("author",
+                                                             "Author",
+                                                             "Email address of the author of the item.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_COMMENTS,
+                                        g_param_spec_string ("comments",
+                                                             "Comments",
+                                                             "URL of a page for comments relating to the item.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_ENCLOSURE,
+                                        g_param_spec_object ("enclosure",
+                                                             "Enclosure",
+                                                             "Describes a media object that is attached to the item.",
+                                                             TYPE_RSSENCLOSURE,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_GUID,
+                                        g_param_spec_object ("guid",
+                                                             "GUID",
+                                                             "A string that uniquely identifies the item.",
+                                                             TYPE_RSSGUID,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_PUB_DATE,
+                                        g_param_spec_pointer ("pub-date",
+                                                              "Publication date",
+                                                              "Indicates when the item was published.",
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_SOURCE,
+                                        g_param_spec_object ("source",
+                                                             "Source",
+                                                             "The RSS channel that the item came from.",
+                                                             TYPE_RSSSOURCE,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+rss_channel_item_init (RssChannelItem *rss)
+{
+}
+
+/**
+ * rss_channel_item_new:
+ * @title: the title of the item.
+ * @description: the item synopsis.
+ *
+ * Returns: the newly created #RssChannelItem object.
+ */
+RssChannelItem
+*rss_channel_item_new (const gchar *title, const gchar *description)
+{
+       g_return_val_if_fail (title != NULL && description != NULL, NULL);
+
+       gchar *_title = g_strstrip (g_strdup (title)),
+             *_description = g_strstrip (g_strdup (description));
+
+       if (strcmp (_title, "") == 0 && strcmp (_description, "") == 0)
+               {
+                       g_critical ("rss_channel_item_new: one of title or description must be present");
+                       return NULL;
+               }
+
+       RssChannelItem *rssci = RSSCHANNELITEM (g_object_new (rss_channel_item_get_type (), NULL));
+
+       g_object_set (G_OBJECT (rssci),
+                     "title", _title,
+                     "description", _description,
+                     NULL);
+
+       return rssci;
+}
+
+/**
+ * rss_channel_item_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ */
+RssChannelItem
+*rss_channel_item_new_from_xml (xmlNode *xnode)
+{
+       g_return_val_if_fail (xnode != NULL, NULL);
+
+       RssChannelItem *rssci = rss_channel_item_new ("title", "description");
+       gboolean title = FALSE, description = FALSE;
+
+       xmlNode *cur = xnode->xmlChildrenNode;
+       while (cur != NULL)
+               {
+                       if (xmlStrcmp (cur->name, (const xmlChar *)"title") == 0)
+                               {
+                                       title = TRUE;
+                                       g_object_set (G_OBJECT (rssci),
+                                                     "title", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"link") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssci),
+                                                     "link", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"description") == 0)
+                               {
+                                       description = TRUE;
+                                       g_object_set (G_OBJECT (rssci),
+                                                     "description", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"author") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssci),
+                                                     "author", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"category") == 0)
+                               {
+                                       rss_channel_item_add_category (rssci, rss_category_new_from_xml (cur));
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"comments") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssci),
+                                                     "comments", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"enclosure") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssci),
+                                                     "enclosure", rss_enclosure_new_from_xml (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"guid") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssci),
+                                                     "guid", rss_guid_new_from_xml (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"pubDate") == 0)
+                               {
+                                       struct tm tm;
+                                       gchar *ret, *text = (gchar *)xmlNodeGetContent (cur);
+                                       ret = (gchar *)strptime (text, "%a, %d %b %Y %T GMT", &tm);
+                                       if (ret != NULL)
+                                               {
+                                                       g_object_set (G_OBJECT (rssci),
+                                                                     "pub-date", &tm,
+                                                                     NULL);
+                                               }
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"image") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssci),
+                                                     "image", rss_image_new_from_xml (cur),
+                                                     NULL);
+                               }
+
+                       cur = cur->next;
+               }
+
+       return (!title || !description ? NULL : rssci);
+}
+
+/**
+ * rss_channel_item_add_category:
+ * @rss_channel_item:
+ * @rss_category:
+ *
+ */
+gboolean
+rss_channel_item_add_category (RssChannelItem *rss_channel_item, RssCategory *rss_category)
+{
+       RssChannelItemPrivate *priv = RSSCHANNELITEM_GET_PRIVATE (rss_channel_item);
+
+       priv->categories = g_list_append (priv->categories, rss_category);
+
+       return TRUE;
+}
+
+/**
+ * rss_channel_item_get_categories:
+ * @rss_channel_item:
+ *
+ */
+GList
+*rss_channel_item_get_categories (RssChannelItem *rss_channel_item)
+{
+       RssChannelItemPrivate *priv = RSSCHANNELITEM_GET_PRIVATE (rss_channel_item);
+
+       return priv->categories;
+}
+
+/**
+ * rss_channel_item_get_xml:
+ * @rss_channel_item: a #RssChannelItem object
+ *
+ * Returns: the #xmlNode correspondent to the item.
+ */
+xmlNode
+*rss_channel_item_get_xml (RssChannelItem *rss_channel_item)
+{
+       char pd[256];
+       GList *categories;
+       RssChannelItemPrivate *priv = RSSCHANNELITEM_GET_PRIVATE (rss_channel_item);
+
+       xmlNode *xnode = xmlNewNode (NULL, (const xmlChar *)"item");
+
+       if (strcmp (priv->title, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"title", (const xmlChar *)priv->title);
+               }
+       if (strcmp (priv->link, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"link", (const xmlChar *)priv->link);
+               }
+       if (strcmp (priv->description, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"description", (const xmlChar *)priv->description);
+               }
+       if (strcmp (priv->author, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"author", (const xmlChar *)priv->author);
+               }
+
+       categories = priv->categories;
+       while (categories != NULL)
+               {
+                       xmlAddChild (xnode, rss_category_get_xml ((RssCategory *)categories->data));
+
+                       categories = g_list_next (categories);
+               }
+
+       if (strcmp (priv->comments, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"comments", (const xmlChar *)priv->comments);
+               }
+
+       if (priv->enclosure != NULL)
+               {
+                       xmlAddChild (xnode, rss_enclosure_get_xml (priv->enclosure));
+               }
+       if (priv->guid != NULL)
+               {
+                       xmlAddChild (xnode, rss_guid_get_xml (priv->guid));
+               }
+
+       if (priv->pubDate != NULL)
+               {
+                       strftime (pd, 256, "%a, %d %b %Y %T GMT", (const struct tm *)priv->pubDate);
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"pubDate", (const xmlChar *)pd);
+               }
+
+       if (priv->source != NULL)
+               {
+                       xmlAddChild (xnode, rss_source_get_xml (priv->source));
+               }
+
+       return xnode;
+}
+
+static void
+rss_channel_item_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       RssChannelItem *rssci = RSSCHANNELITEM (object);
+
+       RssChannelItemPrivate *priv = RSSCHANNELITEM_GET_PRIVATE (rssci);
+
+       switch (property_id)
+               {
+                       case PROP_TITLE:
+                               priv->title = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_LINK:
+                               priv->link = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_DESCRIPTION:
+                               priv->description = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_AUTHOR:
+                               priv->author = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_COMMENTS:
+                               priv->comments = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_ENCLOSURE:
+                               if (g_value_get_object (value) != NULL)
+                                       {
+                                               priv->enclosure = (RssEnclosure *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_GUID:
+                               if (g_value_get_object (value) != NULL)
+                                       {
+                                               priv->guid = (RssGuid *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       case PROP_PUB_DATE:
+                               if (g_value_get_pointer (value) != NULL)
+                                       {
+                                               priv->pubDate = g_memdup ((gconstpointer)g_value_get_pointer (value), sizeof (struct tm));
+                                       }
+                               break;
+
+                       case PROP_SOURCE:
+                               if (g_value_get_object (value) != NULL)
+                                       {
+                                               priv->source = (RssSource *)g_value_dup_object (value);
+                                       }
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+rss_channel_item_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       RssChannelItem *rssci = RSSCHANNELITEM (object);
+
+       RssChannelItemPrivate *priv = RSSCHANNELITEM_GET_PRIVATE (rssci);
+
+       switch (property_id)
+               {
+                       case PROP_TITLE:
+                               g_value_set_string (value, priv->title);
+                               break;
+
+                       case PROP_LINK:
+                               g_value_set_string (value, priv->link);
+                               break;
+
+                       case PROP_DESCRIPTION:
+                               g_value_set_string (value, priv->description);
+                               break;
+
+                       case PROP_AUTHOR:
+                               g_value_set_string (value, priv->author);
+                               break;
+
+                       case PROP_COMMENTS:
+                               g_value_set_string (value, priv->comments);
+                               break;
+
+                       case PROP_ENCLOSURE:
+                               g_value_set_object (value, priv->enclosure);
+                               break;
+
+                       case PROP_GUID:
+                               g_value_set_object (value, priv->guid);
+                               break;
+
+                       case PROP_PUB_DATE:
+                               g_value_set_pointer (value, priv->pubDate);
+                               break;
+
+                       case PROP_SOURCE:
+                               g_value_set_object (value, priv->source);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/rsschannelitem.h b/src/rsschannelitem.h
new file mode 100644 (file)
index 0000000..2bf9f16
--- /dev/null
@@ -0,0 +1,68 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __RSSCHANNELITEMITEM_H__
+#define __RSSCHANNELITEMITEM_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+#include "rsscategory.h"
+
+G_BEGIN_DECLS
+
+
+#define TYPE_RSSCHANNELITEM                 (rss_channel_item_get_type ())
+#define RSSCHANNELITEM(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RSSCHANNELITEM, RssChannelItem))
+#define RSSCHANNELITEM_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RSSCHANNELITEM, RssChannelItemClass))
+#define IS_RSSCHANNELITEM(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RSSCHANNELITEM))
+#define IS_RSSCHANNELITEM_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RSSCHANNELITEM))
+#define RSSCHANNELITEM_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RSSCHANNELITEM, RssChannelItemClass))
+
+
+typedef struct _RssChannelItem RssChannelItem;
+typedef struct _RssChannelItemClass RssChannelItemClass;
+
+struct _RssChannelItem
+       {
+               GObject parent;
+       };
+
+struct _RssChannelItemClass
+       {
+               GObjectClass parent_class;
+       };
+
+GType rss_channel_item_get_type (void) G_GNUC_CONST;
+
+RssChannelItem *rss_channel_item_new (const gchar *title, const gchar *description);
+RssChannelItem *rss_channel_item_new_from_xml (xmlNode *xnode);
+
+gboolean rss_channel_item_add_category (RssChannelItem *rss_channel_item, RssCategory *rss_category);
+GList *rss_channel_item_get_categories (RssChannelItem *rss_channel_item);
+
+xmlNode *rss_channel_item_get_xml (RssChannelItem *rss_channel_item);
+
+
+G_END_DECLS
+
+#endif /* __RSSCHANNELITEM_H__ */
diff --git a/src/rsscloud.c b/src/rsscloud.c
new file mode 100644 (file)
index 0000000..064f57f
--- /dev/null
@@ -0,0 +1,346 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <time.h>
+
+#include <libxml/tree.h>
+
+#include "rsscloud.h"
+
+enum
+{
+       PROP_0,
+       PROP_DOMAIN,
+       PROP_PORT,
+       PROP_PATH,
+       PROP_REGISTER_PROCEDURE,
+       PROP_PROTOCOL
+};
+
+static void rss_cloud_class_init (RssCloudClass *klass);
+static void rss_cloud_init (RssCloud *rss);
+
+static void rss_cloud_set_property (GObject *object,
+                                    guint property_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec);
+static void rss_cloud_get_property (GObject *object,
+                                    guint property_id,
+                                    GValue *value,
+                                    GParamSpec *pspec);
+
+#define RSSCLOUD_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RSSCLOUD, RssCloudPrivate))
+
+typedef struct _RssCloudPrivate RssCloudPrivate;
+struct _RssCloudPrivate
+       {
+               gchar *domain,
+                     *path,
+                     *registerProcedure,
+                     *protocol;
+               guint port;
+       };
+
+GType
+rss_cloud_get_type (void)
+{
+       static GType rss_cloud_type = 0;
+
+       if (!rss_cloud_type)
+               {
+                       static const GTypeInfo rss_cloud_info =
+                       {
+                               sizeof (RssCloudClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) rss_cloud_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (RssCloud),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) rss_cloud_init,
+                               NULL
+                       };
+
+                       rss_cloud_type = g_type_register_static (G_TYPE_OBJECT, "RssCloud",
+                                                                &rss_cloud_info, 0);
+               }
+
+       return rss_cloud_type;
+}
+
+static void
+rss_cloud_class_init (RssCloudClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (RssCloudPrivate));
+
+       object_class->set_property = rss_cloud_set_property;
+       object_class->get_property = rss_cloud_get_property;
+
+       g_object_class_install_property (object_class, PROP_DOMAIN,
+                                        g_param_spec_string ("domain",
+                                                             "Domain",
+                                                             "Domain",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_PORT,
+                                        g_param_spec_uint ("port",
+                                                           "Port",
+                                                           "Port",
+                                                           1,
+                                                           65565,
+                                                           80,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_PATH,
+                                        g_param_spec_string ("path",
+                                                             "Path",
+                                                             "Path",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_REGISTER_PROCEDURE,
+                                        g_param_spec_string ("register-procedure",
+                                                             "Register Procedure",
+                                                             "Register Procedure",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_PROTOCOL,
+                                        g_param_spec_string ("protocol",
+                                                             "Protocol",
+                                                             "Protocol",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+rss_cloud_init (RssCloud *rss)
+{
+}
+
+/**
+ * rss_cloud_new:
+ * @domain:
+ * @port:
+ * @path:
+ * @registerProcedure:
+ * @protocol:
+ *
+ * Returns: the newly created #RssCloud object.
+ */
+RssCloud
+*rss_cloud_new (const gchar *domain,
+                guint port,
+                const gchar *path,
+                const gchar *registerProcedure,
+                const gchar *protocol)
+{
+       g_return_val_if_fail (domain != NULL, NULL);
+       g_return_val_if_fail (port > 0 && port < 65565, NULL);
+       g_return_val_if_fail (path != NULL, NULL);
+       g_return_val_if_fail (registerProcedure != NULL, NULL);
+       g_return_val_if_fail (protocol != NULL, NULL);
+
+       gchar *_domain = g_strstrip (g_strdup (domain)),
+             *_path = g_strstrip (g_strdup (path)),
+             *_registerProcedure = g_strstrip (g_strdup (registerProcedure)),
+             *_protocol = g_strstrip (g_strdup (protocol));
+
+       if (strcmp (_domain, "") == 0)
+               {
+                       g_critical ("rss_cloud_new: domain cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_path, "") == 0)
+               {
+                       g_critical ("rss_cloud_new: path cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_registerProcedure, "") == 0)
+               {
+                       g_critical ("rss_cloud_new: registerProcedure cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_protocol, "") == 0)
+               {
+                       g_critical ("rss_cloud_new: protocol cannot be an empty string");
+                       return NULL;
+               }
+
+       RssCloud *rssc = RSSCLOUD (g_object_new (rss_cloud_get_type (), NULL));
+
+       g_object_set (G_OBJECT (rssc),
+                     "domain", _domain,
+                     "port", port,
+                     "path", _path,
+                     "register-procedure", _registerProcedure,
+                     "protocol", _protocol,
+                     NULL);
+
+       return rssc;
+}
+
+/**
+ * rss_cloud_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ */
+RssCloud
+*rss_cloud_new_from_xml (xmlNode *xnode)
+{
+       g_return_val_if_fail (xnode != NULL, NULL);
+
+       RssCloud *rssc = rss_cloud_new ("domain", 80, "path", "register-procedure", "protocol");
+       gboolean domain = FALSE, port = FALSE, path = FALSE,
+                registerProcedure = FALSE, protocol = FALSE;
+
+       xmlChar *prop;
+
+       if ((prop = xmlGetProp (xnode, (const xmlChar *)"domain")) != NULL)
+               {
+                       domain = TRUE;
+                       g_object_set (G_OBJECT (rssc),
+                                     "domain", (gchar *)prop,
+                                     NULL);
+               }
+       if ((prop = xmlGetProp (xnode, (const xmlChar *)"port")) != NULL)
+               {
+                       port = TRUE;
+                       g_object_set (G_OBJECT (rssc),
+                                     "port", atol ((char *)prop),
+                                     NULL);
+               }
+       if ((prop = xmlGetProp (xnode, (const xmlChar *)"path")) != NULL)
+               {
+                       path = TRUE;
+                       g_object_set (G_OBJECT (rssc),
+                                     "path", (gchar *)prop,
+                                     NULL);
+               }
+       if ((prop = xmlGetProp (xnode, (const xmlChar *)"registerProcedure")) != NULL)
+               {
+                       registerProcedure = TRUE;
+                       g_object_set (G_OBJECT (rssc),
+                                     "register-procedure", (gchar *)prop,
+                                     NULL);
+               }
+       if ((prop = xmlGetProp (xnode, (const xmlChar *)"protocol")) != NULL)
+               {
+                       protocol = TRUE;
+                       g_object_set (G_OBJECT (rssc),
+                                     "protocol", (gchar *)prop,
+                                     NULL);
+               }
+
+       return (!domain || !port || !path || !registerProcedure || !protocol ? NULL : rssc);
+}
+
+/**
+ * rss_cloud_get_xml:
+ * @rss_cloud: a #RssCloud object
+ *
+ * Returns: the #xmlNode correspondent to the item.
+ */
+xmlNode
+*rss_cloud_get_xml (RssCloud *rss_cloud)
+{
+       RssCloudPrivate *priv = RSSCLOUD_GET_PRIVATE (rss_cloud);
+
+       xmlNode *xnode = xmlNewNode (NULL, (const xmlChar *)"cloud");
+
+       xmlSetProp (xnode, (const xmlChar *)"domain", (const xmlChar *)priv->domain);
+       xmlSetProp (xnode, (const xmlChar *)"port", (const xmlChar *)g_strdup_printf ("%d", priv->port));
+       xmlSetProp (xnode, (const xmlChar *)"path", (const xmlChar *)priv->path);
+       xmlSetProp (xnode, (const xmlChar *)"registerProcedure", (const xmlChar *)priv->registerProcedure);
+       xmlSetProp (xnode, (const xmlChar *)"protocol", (const xmlChar *)priv->protocol);
+
+       return xnode;
+}
+
+static void
+rss_cloud_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       RssCloud *rssc = RSSCLOUD (object);
+
+       RssCloudPrivate *priv = RSSCLOUD_GET_PRIVATE (rssc);
+
+       switch (property_id)
+               {
+                       case PROP_DOMAIN:
+                               priv->domain = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_PORT:
+                               priv->port = g_value_get_uint (value);
+                               break;
+
+                       case PROP_PATH:
+                               priv->path = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_REGISTER_PROCEDURE:
+                               priv->registerProcedure = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_PROTOCOL:
+                               priv->protocol = g_strdup (g_value_get_string (value));
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+rss_cloud_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       RssCloud *rssc = RSSCLOUD (object);
+
+       RssCloudPrivate *priv = RSSCLOUD_GET_PRIVATE (rssc);
+
+       switch (property_id)
+               {
+                       case PROP_DOMAIN:
+                               g_value_set_string (value, priv->domain);
+                               break;
+
+                       case PROP_PORT:
+                               g_value_set_uint (value, priv->port);
+                               break;
+
+                       case PROP_PATH:
+                               g_value_set_string (value, priv->path);
+                               break;
+
+                       case PROP_REGISTER_PROCEDURE:
+                               g_value_set_string (value, priv->registerProcedure);
+                               break;
+
+                       case PROP_PROTOCOL:
+                               g_value_set_string (value, priv->protocol);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/rsscloud.h b/src/rsscloud.h
new file mode 100644 (file)
index 0000000..f84590a
--- /dev/null
@@ -0,0 +1,67 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __RSSCLOUD_H__
+#define __RSSCLOUD_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+G_BEGIN_DECLS
+
+
+#define TYPE_RSSCLOUD                 (rss_cloud_get_type ())
+#define RSSCLOUD(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RSSCLOUD, RssCloud))
+#define RSSCLOUD_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RSSCLOUD, RssCloudClass))
+#define IS_RSSCLOUD(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RSSCLOUD))
+#define IS_RSSCLOUD_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RSSCLOUD))
+#define RSSCLOUD_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RSSCLOUD, RssCloudClass))
+
+
+typedef struct _RssCloud RssCloud;
+typedef struct _RssCloudClass RssCloudClass;
+
+struct _RssCloud
+       {
+               GObject parent;
+       };
+
+struct _RssCloudClass
+       {
+               GObjectClass parent_class;
+       };
+
+GType rss_cloud_get_type (void) G_GNUC_CONST;
+
+RssCloud *rss_cloud_new (const gchar *domain,
+                         guint port,
+                         const gchar *path,
+                         const gchar *registerProcedure,
+                         const gchar *protocol);
+RssCloud *rss_cloud_new_from_xml (xmlNode *xnode);
+
+xmlNode *rss_cloud_get_xml (RssCloud *rss_cloud);
+
+
+G_END_DECLS
+
+#endif /* __RSSCLOUD_H__ */
diff --git a/src/rssenclosure.c b/src/rssenclosure.c
new file mode 100644 (file)
index 0000000..a819b70
--- /dev/null
@@ -0,0 +1,274 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <time.h>
+
+#include <libxml/tree.h>
+
+#include "rssenclosure.h"
+
+enum
+{
+       PROP_0,
+       PROP_URL,
+       PROP_PORT,
+       PROP_LENGTH,
+       PROP_TYPE
+};
+
+static void rss_enclosure_class_init (RssEnclosureClass *klass);
+static void rss_enclosure_init (RssEnclosure *rss);
+
+static void rss_enclosure_set_property (GObject *object,
+                                        guint property_id,
+                                        const GValue *value,
+                                        GParamSpec *pspec);
+static void rss_enclosure_get_property (GObject *object,
+                                        guint property_id,
+                                        GValue *value,
+                                        GParamSpec *pspec);
+
+#define RSSENCLOSURE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RSSENCLOSURE, RssEnclosurePrivate))
+
+typedef struct _RssEnclosurePrivate RssEnclosurePrivate;
+struct _RssEnclosurePrivate
+       {
+               gchar *url,
+                     *type;
+               gulong length;
+       };
+
+GType
+rss_enclosure_get_type (void)
+{
+       static GType rss_enclosure_type = 0;
+
+       if (!rss_enclosure_type)
+               {
+                       static const GTypeInfo rss_enclosure_info =
+                       {
+                               sizeof (RssEnclosureClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) rss_enclosure_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (RssEnclosure),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) rss_enclosure_init,
+                               NULL
+                       };
+
+                       rss_enclosure_type = g_type_register_static (G_TYPE_OBJECT, "RssEnclosure",
+                                                                    &rss_enclosure_info, 0);
+               }
+
+       return rss_enclosure_type;
+}
+
+static void
+rss_enclosure_class_init (RssEnclosureClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (RssEnclosurePrivate));
+
+       object_class->set_property = rss_enclosure_set_property;
+       object_class->get_property = rss_enclosure_get_property;
+
+       g_object_class_install_property (object_class, PROP_URL,
+                                        g_param_spec_string ("url",
+                                                             "URL",
+                                                             "Where the enclosure is located.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_LENGTH,
+                                        g_param_spec_ulong ("length",
+                                                            "Length",
+                                                            "How big it is in bytes.",
+                                                            0,
+                                                            ULONG_MAX,
+                                                            0,
+                                                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_TYPE,
+                                        g_param_spec_string ("type",
+                                                             "Type",
+                                                             "What its type is, a standard MIME type.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+rss_enclosure_init (RssEnclosure *rss)
+{
+}
+
+/**
+ * rss_enclosure_new:
+ * @url: Where the enclosure is located.
+ * @length: How big it is in bytes.
+ * @type: What its type is, a standard MIME type.
+ *
+ * Returns: the newly created #RssEnclosure object.
+ */
+RssEnclosure
+*rss_enclosure_new (const gchar *url,
+                    gulong length,
+                    const gchar *type)
+{
+       g_return_val_if_fail (url != NULL, NULL);
+       g_return_val_if_fail (type != NULL, NULL);
+
+       gchar *_url = g_strstrip (g_strdup (url)),
+             *_type = g_strstrip (g_strdup (type));
+
+       if (strcmp (_url, "") == 0)
+               {
+                       g_critical ("rss_enclosure_new: url cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_type, "") == 0)
+               {
+                       g_critical ("rss_enclosure_new: type cannot be an empty string");
+                       return NULL;
+               }
+
+       RssEnclosure *rsse = RSSENCLOSURE (g_object_new (rss_enclosure_get_type (), NULL));
+
+       g_object_set (G_OBJECT (rsse),
+                     "url", _url,
+                     "length", length,
+                     "type", _type,
+                     NULL);
+
+       return rsse;
+}
+
+/**
+ * rss_enclosure_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ */
+RssEnclosure
+*rss_enclosure_new_from_xml (xmlNode *xnode)
+{
+       g_return_val_if_fail (xnode != NULL, NULL);
+
+       RssEnclosure *rsse = rss_enclosure_new ("url", 1, "type");
+       gboolean url = FALSE, length = FALSE, type = FALSE;
+
+       xmlChar *prop;
+
+       if ((prop = xmlGetProp (xnode, (const xmlChar *)"url")) != NULL)
+               {
+                       g_object_set (G_OBJECT (rsse),
+                                     "url", (gchar *)prop,
+                                     NULL);
+               }
+       if ((prop = xmlGetProp (xnode, (const xmlChar *)"length")) != NULL)
+               {
+                       g_object_set (G_OBJECT (rsse),
+                                     "length", atol ((char *)prop),
+                                     NULL);
+               }
+       if ((prop = xmlGetProp (xnode, (const xmlChar *)"type")) != NULL)
+               {
+                       g_object_set (G_OBJECT (rsse),
+                                     "type", (gchar *)prop,
+                                     NULL);
+               }
+
+       return (!url || !length || !type ? NULL : rsse);
+}
+
+/**
+ * rss_enclosure_get_xml:
+ * @rss_enclosure: a #RssEnclosure object
+ *
+ * Returns: the #xmlNode correspondent to the item.
+ */
+xmlNode
+*rss_enclosure_get_xml (RssEnclosure *rss_enclosure)
+{
+       RssEnclosurePrivate *priv = RSSENCLOSURE_GET_PRIVATE (rss_enclosure);
+
+       xmlNode *xnode = xmlNewNode (NULL, (const xmlChar *)"enclosure");
+
+       xmlSetProp (xnode, (const xmlChar *)"url", (const xmlChar *)priv->url);
+       xmlSetProp (xnode, (const xmlChar *)"length", (const xmlChar *)g_strdup_printf ("%d", priv->length));
+       xmlSetProp (xnode, (const xmlChar *)"type", (const xmlChar *)priv->type);
+
+       return xnode;
+}
+
+static void
+rss_enclosure_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       RssEnclosure *rsse = RSSENCLOSURE (object);
+
+       RssEnclosurePrivate *priv = RSSENCLOSURE_GET_PRIVATE (rsse);
+
+       switch (property_id)
+               {
+                       case PROP_URL:
+                               priv->url = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_LENGTH:
+                               priv->length = g_value_get_ulong (value);
+                               break;
+
+                       case PROP_TYPE:
+                               priv->type = g_strdup (g_value_get_string (value));
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+rss_enclosure_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       RssEnclosure *rsse = RSSENCLOSURE (object);
+
+       RssEnclosurePrivate *priv = RSSENCLOSURE_GET_PRIVATE (rsse);
+
+       switch (property_id)
+               {
+                       case PROP_URL:
+                               g_value_set_string (value, priv->url);
+                               break;
+
+                       case PROP_LENGTH:
+                               g_value_set_ulong (value, priv->length);
+                               break;
+
+                       case PROP_TYPE:
+                               g_value_set_string (value, priv->type);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/rssenclosure.h b/src/rssenclosure.h
new file mode 100644 (file)
index 0000000..f6bdde8
--- /dev/null
@@ -0,0 +1,65 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __RSSENCLOSURE_H__
+#define __RSSENCLOSURE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+G_BEGIN_DECLS
+
+
+#define TYPE_RSSENCLOSURE                 (rss_enclosure_get_type ())
+#define RSSENCLOSURE(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RSSENCLOSURE, RssEnclosure))
+#define RSSENCLOSURE_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RSSENCLOSURE, RssEnclosureClass))
+#define IS_RSSENCLOSURE(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RSSENCLOSURE))
+#define IS_RSSENCLOSURE_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RSSENCLOSURE))
+#define RSSENCLOSURE_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RSSENCLOSURE, RssEnclosureClass))
+
+
+typedef struct _RssEnclosure RssEnclosure;
+typedef struct _RssEnclosureClass RssEnclosureClass;
+
+struct _RssEnclosure
+       {
+               GObject parent;
+       };
+
+struct _RssEnclosureClass
+       {
+               GObjectClass parent_class;
+       };
+
+GType rss_enclosure_get_type (void) G_GNUC_CONST;
+
+RssEnclosure *rss_enclosure_new (const gchar *url,
+                                 gulong length,
+                                 const gchar *type);
+RssEnclosure *rss_enclosure_new_from_xml (xmlNode *xnode);
+
+xmlNode *rss_enclosure_get_xml (RssEnclosure *rss_enclosure);
+
+
+G_END_DECLS
+
+#endif /* __RSSENCLOSURE_H__ */
diff --git a/src/rssguid.c b/src/rssguid.c
new file mode 100644 (file)
index 0000000..5d64806
--- /dev/null
@@ -0,0 +1,243 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <time.h>
+
+#include <libxml/tree.h>
+
+#include "rssguid.h"
+
+enum
+{
+       PROP_0,
+       PROP_GUID,
+       PROP_IS_PERMALINK
+};
+
+static void rss_guid_class_init (RssGuidClass *klass);
+static void rss_guid_init (RssGuid *rss);
+
+static void rss_guid_set_property (GObject *object,
+                                   guint property_id,
+                                   const GValue *value,
+                                   GParamSpec *pspec);
+static void rss_guid_get_property (GObject *object,
+                                   guint property_id,
+                                   GValue *value,
+                                   GParamSpec *pspec);
+
+#define RSSGUID_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RSSGUID, RssGuidPrivate))
+
+typedef struct _RssGuidPrivate RssGuidPrivate;
+struct _RssGuidPrivate
+       {
+               gchar *guid;
+               gboolean isPermaLink;
+       };
+
+GType
+rss_guid_get_type (void)
+{
+       static GType rss_guid_type = 0;
+
+       if (!rss_guid_type)
+               {
+                       static const GTypeInfo rss_guid_info =
+                       {
+                               sizeof (RssGuidClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) rss_guid_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (RssGuid),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) rss_guid_init,
+                               NULL
+                       };
+
+                       rss_guid_type = g_type_register_static (G_TYPE_OBJECT, "RssGuid",
+                                                               &rss_guid_info, 0);
+               }
+
+       return rss_guid_type;
+}
+
+static void
+rss_guid_class_init (RssGuidClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (RssGuidPrivate));
+
+       object_class->set_property = rss_guid_set_property;
+       object_class->get_property = rss_guid_get_property;
+
+       g_object_class_install_property (object_class, PROP_GUID,
+                                        g_param_spec_string ("guid",
+                                                             "GUID",
+                                                             "A string that uniquely identifies the item (Global Unique Identifier).",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_IS_PERMALINK,
+                                        g_param_spec_boolean ("is-permalink",
+                                                              "Is PermaLink",
+                                                              "True if GUID is a url that can be opened in a Web browser.",
+                                                              TRUE,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+rss_guid_init (RssGuid *rss)
+{
+}
+
+/**
+ * rss_guid_new:
+ * @guid: A string that uniquely identifies the item (Global Unique Identifier).
+ *
+ * Returns: the newly created #RssGuid object.
+ */
+RssGuid
+*rss_guid_new (const gchar *guid)
+{
+       g_return_val_if_fail (guid != NULL, NULL);
+
+       gchar *_guid = g_strstrip (g_strdup (guid));
+
+       if (strcmp (_guid, "") == 0)
+               {
+                       g_critical ("rss_guid_new: guid cannot be an empty string");
+                       return NULL;
+               }
+
+       RssGuid *rssg = RSSGUID (g_object_new (rss_guid_get_type (), NULL));
+
+       g_object_set (G_OBJECT (rssg),
+                     "guid", _guid,
+                     NULL);
+
+       return rssg;
+}
+
+/**
+ * rss_guid_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ * Returns: the newly created #RssGuid object.
+ */
+RssGuid
+*rss_guid_new_from_xml (xmlNode *xnode)
+{
+       g_return_val_if_fail (xnode != NULL, NULL);
+
+       RssGuid *rssg = rss_guid_new ("guid");
+       gboolean guid = FALSE;
+
+       xmlChar *prop;
+
+       if ((prop = xmlGetProp (xnode, (const xmlChar *)"isPermaLink")) != NULL)
+               {
+                       g_object_set (G_OBJECT (rssg),
+                                     "is-permalink", (gchar *)prop,
+                                     NULL);
+               }
+
+       gchar *text = (gchar *)xmlNodeGetContent (xnode);
+       if (strcmp (g_strstrip (text), "") != 0)
+               {
+                       guid = TRUE;
+                       g_object_set (G_OBJECT (rssg),
+                                     "guid", text,
+                                     NULL);
+               }
+
+       return (!guid ? NULL : rssg);
+}
+
+/**
+ * rss_guid_get_xml:
+ * @rss_guid: a #RssGuid object.
+ *
+ * Returns: the #xmlNode correspondent to the item.
+ */
+xmlNode
+*rss_guid_get_xml (RssGuid *rss_guid)
+{
+       RssGuidPrivate *priv = RSSGUID_GET_PRIVATE (rss_guid);
+
+       xmlNode *xnode = xmlNewNode (NULL, (const xmlChar *)"guid");
+
+       xmlAddChild (xnode, xmlNewText ((const xmlChar *)priv->guid));
+
+       if (!priv->isPermaLink)
+               {
+                       xmlSetProp (xnode, (const xmlChar *)"isPermaLink", (const xmlChar *)"false");
+               }
+
+       return xnode;
+}
+
+static void
+rss_guid_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       RssGuid *rssc = RSSGUID (object);
+
+       RssGuidPrivate *priv = RSSGUID_GET_PRIVATE (rssc);
+
+       switch (property_id)
+               {
+                       case PROP_GUID:
+                               priv->guid = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_IS_PERMALINK:
+                               priv->isPermaLink = g_value_get_boolean (value);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+rss_guid_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       RssGuid *rssc = RSSGUID (object);
+
+       RssGuidPrivate *priv = RSSGUID_GET_PRIVATE (rssc);
+
+       switch (property_id)
+               {
+                       case PROP_GUID:
+                               g_value_set_string (value, priv->guid);
+                               break;
+
+                       case PROP_IS_PERMALINK:
+                               g_value_set_boolean (value, priv->isPermaLink);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/rssguid.h b/src/rssguid.h
new file mode 100644 (file)
index 0000000..8c7bcec
--- /dev/null
@@ -0,0 +1,63 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __RSSGUID_H__
+#define __RSSGUID_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+G_BEGIN_DECLS
+
+
+#define TYPE_RSSGUID                 (rss_cloud_get_type ())
+#define RSSGUID(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RSSGUID, RssGuid))
+#define RSSGUID_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RSSGUID, RssGuidClass))
+#define IS_RSSGUID(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RSSGUID))
+#define IS_RSSGUID_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RSSGUID))
+#define RSSGUID_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RSSGUID, RssGuidClass))
+
+
+typedef struct _RssGuid RssGuid;
+typedef struct _RssGuidClass RssGuidClass;
+
+struct _RssGuid
+       {
+               GObject parent;
+       };
+
+struct _RssGuidClass
+       {
+               GObjectClass parent_class;
+       };
+
+GType rss_guid_get_type (void) G_GNUC_CONST;
+
+RssGuid *rss_guid_new (const gchar *guid);
+RssGuid *rss_guid_new_from_xml (xmlNode *xnode);
+
+xmlNode *rss_guid_get_xml (RssGuid *rss_guid);
+
+
+G_END_DECLS
+
+#endif /* __RSSGUID_H__ */
diff --git a/src/rssimage.c b/src/rssimage.c
new file mode 100644 (file)
index 0000000..f3eae4e
--- /dev/null
@@ -0,0 +1,363 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <time.h>
+
+#include <libxml/tree.h>
+
+#include "rssimage.h"
+
+enum
+{
+       PROP_0,
+       PROP_URL,
+       PROP_TITLE,
+       PROP_LINK,
+       PROP_WIDTH,
+       PROP_HEIGHT,
+       PROP_DESCRIPTION
+};
+
+static void rss_image_class_init (RssImageClass *klass);
+static void rss_image_init (RssImage *rss);
+
+static void rss_image_set_property (GObject *object,
+                                           guint property_id,
+                                           const GValue *value,
+                                           GParamSpec *pspec);
+static void rss_image_get_property (GObject *object,
+                                           guint property_id,
+                                           GValue *value,
+                                           GParamSpec *pspec);
+
+#define RSSIMAGE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RSSIMAGE, RssImagePrivate))
+
+typedef struct _RssImagePrivate RssImagePrivate;
+struct _RssImagePrivate
+       {
+               gchar *url,
+                     *title,
+                     *link,
+                     *description;
+               guint width, height;
+       };
+
+GType
+rss_image_get_type (void)
+{
+       static GType rss_image_type = 0;
+
+       if (!rss_image_type)
+               {
+                       static const GTypeInfo rss_image_info =
+                       {
+                               sizeof (RssImageClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) rss_image_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (RssImage),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) rss_image_init,
+                               NULL
+                       };
+
+                       rss_image_type = g_type_register_static (G_TYPE_OBJECT, "RssImage",
+                                                                &rss_image_info, 0);
+               }
+
+       return rss_image_type;
+}
+
+static void
+rss_image_class_init (RssImageClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (RssImagePrivate));
+
+       object_class->set_property = rss_image_set_property;
+       object_class->get_property = rss_image_get_property;
+
+       g_object_class_install_property (object_class, PROP_URL,
+                                        g_param_spec_string ("url",
+                                                             "URL",
+                                                             "The URL of a GIF, JPEG or PNG image",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_TITLE,
+                                        g_param_spec_string ("title",
+                                                             "Title",
+                                                             "Describes the image, it is used in the ALT attribute of the HTML img tag when the channel is rendered in HTML",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_LINK,
+                                        g_param_spec_string ("link",
+                                                             "Link",
+                                                             "Is the URL of the site, when the channel is rendered, the image is a link to the site",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_WIDTH,
+                                        g_param_spec_uint ("width",
+                                                           "Width",
+                                                           "The width of the image in pixels",
+                                                           0,
+                                                           144,
+                                                           88,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_HEIGHT,
+                                        g_param_spec_uint ("height",
+                                                           "Height",
+                                                           "The height of the image in pixels",
+                                                           0,
+                                                           400,
+                                                           31,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_DESCRIPTION,
+                                        g_param_spec_string ("description",
+                                                             "Description",
+                                                             "Contains text that is included in the TITLE attribute of the link formed around the image in the HTML rendering",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+rss_image_init (RssImage *rss)
+{
+}
+
+/**
+ * rss_image_new:
+ * @url: the URL of a GIF, JPEG or PNG image.
+ * @title: describes the image, it is used in the ALT attribute of the HTML img tag when the channel is rendered in HTML.
+ * @link: iIs the URL of the site, when the channel is rendered, the image is a link to the site.
+ *
+ * Returns: the newly created #RssImage object.
+ */
+RssImage
+*rss_image_new (const gchar *url, const gchar *title, const gchar *link)
+{
+       g_return_val_if_fail (url != NULL, NULL);
+       g_return_val_if_fail (title != NULL, NULL);
+       g_return_val_if_fail (link != NULL, NULL);
+
+       gchar *_url = g_strstrip (g_strdup (url)),
+             *_title = g_strstrip (g_strdup (title)),
+             *_link = g_strstrip (g_strdup (link));
+
+       if (strcmp (_url, "") == 0)
+               {
+                       g_critical ("rss_image_new: url cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_title, "") == 0)
+               {
+                       g_critical ("rss_image_new: title cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_link, "") == 0)
+               {
+                       g_critical ("rss_image_new: link cannot be an empty string");
+                       return NULL;
+               }
+
+       RssImage *rssi = RSSIMAGE (g_object_new (rss_image_get_type (), NULL));
+
+       g_object_set (G_OBJECT (rssi),
+                     "url", _url,
+                     "title", _title,
+                     "link", _link,
+                     NULL);
+
+       return rssi;
+}
+
+/**
+ * rss_image_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ */
+RssImage
+*rss_image_new_from_xml (xmlNode *xnode)
+{
+       RssImage *rssi = rss_image_new ("url", "title", "link");
+       gboolean url = FALSE, title = FALSE, link = FALSE;
+
+       xmlNode *cur = xnode->xmlChildrenNode;
+       while (cur != NULL)
+               {
+                       if (xmlStrcmp (cur->name, (const xmlChar *)"url") == 0)
+                               {
+                                       url = TRUE;
+                                       g_object_set (G_OBJECT (rssi),
+                                                     "url", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"title") == 0)
+                               {
+                                       title = TRUE;
+                                       g_object_set (G_OBJECT (rssi),
+                                                     "title", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"link") == 0)
+                               {
+                                       link = TRUE;
+                                       g_object_set (G_OBJECT (rssi),
+                                                     "link", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"width") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssi),
+                                                     "width", atol ((char *)xmlNodeGetContent (cur)),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"height") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssi),
+                                                     "height", atol ((char *)xmlNodeGetContent (cur)),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"description") == 0)
+                               {
+                                       g_object_set (G_OBJECT (rssi),
+                                                     "description", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+
+                       cur = cur->next;
+               }
+
+       return (!url || !title || !link ? NULL : rssi);
+}
+
+/**
+ * rss_image_get_xml:
+ * @rss_image: a #RssImage object.
+ *
+ * Returns: the #xmlNode correspondent to the item.
+ */
+xmlNode
+*rss_image_get_xml (RssImage *rss_image)
+{
+       RssImagePrivate *priv = RSSIMAGE_GET_PRIVATE (rss_image);
+
+       xmlNode *xnode = xmlNewNode (NULL, (const xmlChar *)"image");
+
+       xmlNewTextChild (xnode, NULL, (const xmlChar *)"url", (const xmlChar *)priv->url);
+       xmlNewTextChild (xnode, NULL, (const xmlChar *)"title", (const xmlChar *)priv->title);
+       xmlNewTextChild (xnode, NULL, (const xmlChar *)"link", (const xmlChar *)priv->link);
+
+       if (priv->width != 88)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"width", (const xmlChar *)g_strdup_printf ("%d", priv->width));
+               }
+       if (priv->height != 31)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"height", (const xmlChar *)g_strdup_printf ("%d", priv->height));
+               }
+       if (strcmp (priv->description, "") != 0)
+               {
+                       xmlNewTextChild (xnode, NULL, (const xmlChar *)"description", (const xmlChar *)priv->description);
+               }
+
+       return xnode;
+}
+
+static void
+rss_image_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       RssImage *rssi = RSSIMAGE (object);
+
+       RssImagePrivate *priv = RSSIMAGE_GET_PRIVATE (rssi);
+
+       switch (property_id)
+               {
+                       case PROP_URL:
+                               priv->url = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_TITLE:
+                               priv->title = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_LINK:
+                               priv->link = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_WIDTH:
+                               priv->width = g_value_get_uint (value);
+                               break;
+
+                       case PROP_HEIGHT:
+                               priv->height = g_value_get_uint (value);
+                               break;
+
+                       case PROP_DESCRIPTION:
+                               priv->description = g_strdup (g_value_get_string (value));
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+rss_image_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       RssImage *rssi = RSSIMAGE (object);
+
+       RssImagePrivate *priv = RSSIMAGE_GET_PRIVATE (rssi);
+
+       switch (property_id)
+               {
+                       case PROP_URL:
+                               g_value_set_string (value, priv->url);
+                               break;
+
+                       case PROP_TITLE:
+                               g_value_set_string (value, priv->title);
+                               break;
+
+                       case PROP_LINK:
+                               g_value_set_string (value, priv->link);
+                               break;
+
+                       case PROP_WIDTH:
+                               g_value_set_uint (value, priv->width);
+                               break;
+
+                       case PROP_HEIGHT:
+                               g_value_set_uint (value, priv->height);
+                               break;
+
+                       case PROP_DESCRIPTION:
+                               g_value_set_string (value, priv->description);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/rssimage.h b/src/rssimage.h
new file mode 100644 (file)
index 0000000..c11d791
--- /dev/null
@@ -0,0 +1,63 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __RSSIMAGE_H__
+#define __RSSIMAGE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+G_BEGIN_DECLS
+
+
+#define TYPE_RSSIMAGE                 (rss_image_get_type ())
+#define RSSIMAGE(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RSSIMAGE, RssImage))
+#define RSSIMAGE_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RSSIMAGE, RssImageClass))
+#define IS_RSSIMAGE(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RSSIMAGE))
+#define IS_RSSIMAGE_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RSSIMAGE))
+#define RSSIMAGE_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RSSIMAGE, RssImageClass))
+
+
+typedef struct _RssImage RssImage;
+typedef struct _RssImageClass RssImageClass;
+
+struct _RssImage
+       {
+               GObject parent;
+       };
+
+struct _RssImageClass
+       {
+               GObjectClass parent_class;
+       };
+
+GType rss_image_get_type (void) G_GNUC_CONST;
+
+RssImage *rss_image_new (const gchar *url, const gchar *title, const gchar *link);
+RssImage *rss_image_new_from_xml (xmlNode *xnode);
+
+xmlNode *rss_image_get_xml (RssImage *rss_image);
+
+
+G_END_DECLS
+
+#endif /* __RSSIMAGE_H__ */
diff --git a/src/rsssource.c b/src/rsssource.c
new file mode 100644 (file)
index 0000000..c8082c1
--- /dev/null
@@ -0,0 +1,247 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <time.h>
+
+#include <libxml/tree.h>
+
+#include "rsssource.h"
+
+enum
+{
+       PROP_0,
+       PROP_TITLE,
+       PROP_URL
+};
+
+static void rss_source_class_init (RssSourceClass *klass);
+static void rss_source_init (RssSource *rss);
+
+static void rss_source_set_property (GObject *object,
+                                     guint property_id,
+                                     const GValue *value,
+                                     GParamSpec *pspec);
+static void rss_source_get_property (GObject *object,
+                                     guint property_id,
+                                     GValue *value,
+                                     GParamSpec *pspec);
+
+#define RSSSOURCE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RSSSOURCE, RssSourcePrivate))
+
+typedef struct _RssSourcePrivate RssSourcePrivate;
+struct _RssSourcePrivate
+       {
+               gchar *title,
+                     *url;
+       };
+
+GType
+rss_source_get_type (void)
+{
+       static GType rss_source_type = 0;
+
+       if (!rss_source_type)
+               {
+                       static const GTypeInfo rss_source_info =
+                       {
+                               sizeof (RssSourceClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) rss_source_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (RssSource),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) rss_source_init,
+                               NULL
+                       };
+
+                       rss_source_type = g_type_register_static (G_TYPE_OBJECT, "RssSource",
+                                                                 &rss_source_info, 0);
+               }
+
+       return rss_source_type;
+}
+
+static void
+rss_source_class_init (RssSourceClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (RssSourcePrivate));
+
+       object_class->set_property = rss_source_set_property;
+       object_class->get_property = rss_source_get_property;
+
+       g_object_class_install_property (object_class, PROP_TITLE,
+                                        g_param_spec_string ("title",
+                                                             "Title",
+                                                             "Title of the source which the item came from.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_URL,
+                                        g_param_spec_string ("url",
+                                                             "URL",
+                                                             "Links to the XMLization of the source.",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+rss_source_init (RssSource *rss)
+{
+}
+
+/**
+ * rss_source_new:
+ * @title: Title of the source which the item came from.
+ * @url: Links to the XMLization of the source.
+ *
+ * Returns: the newly created #RssSource object.
+ */
+RssSource
+*rss_source_new (const gchar *title, const gchar *url)
+{
+       g_return_val_if_fail (title != NULL, NULL);
+       g_return_val_if_fail (url != NULL, NULL);
+
+       gchar *_title = g_strstrip (g_strdup (title)),
+             *_url = g_strstrip (g_strdup (url));
+
+       if (strcmp (_title, "") == 0)
+               {
+                       g_critical ("rss_source_new: title cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_url, "") == 0)
+               {
+                       g_critical ("rss_source_new: url cannot be an empty string");
+                       return NULL;
+               }
+
+       RssSource *rsss = RSSSOURCE (g_object_new (rss_source_get_type (), NULL));
+
+       g_object_set (G_OBJECT (rsss),
+                     "title", _title,
+                     "url", _url,
+                     NULL);
+
+       return rsss;
+}
+
+/**
+ * rss_source_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ */
+RssSource
+*rss_source_new_from_xml (xmlNode *xnode)
+{
+       RssSource *rsss = rss_source_new ("title", "url");
+       gboolean title = FALSE, url = FALSE;
+       gchar *str_title, *str_url;
+
+       str_url = (gchar *)xmlGetProp (xnode, (const xmlChar *)"url");
+       if (str_url != NULL || strcmp (g_strstrip (str_url), "") != 0)
+               {
+                       url = TRUE;
+                       g_object_set (G_OBJECT (rsss),
+                                     "url", str_url,
+                                     NULL);
+               }
+
+       str_title = (gchar *)xmlNodeGetContent ((xmlNodePtr)xnode);
+       if (str_title != NULL && strcmp (g_strstrip (str_title), "") != 0)
+               {
+                       title = TRUE;
+                       g_object_set (G_OBJECT (rsss),
+                                     "title", str_title,
+                                     NULL);
+               }
+
+       return (!title || !url ? NULL : rsss);
+}
+
+/**
+ * rss_source_get_xml:
+ * @rss_source: a #RssSource object
+ *
+ * Returns: the #xmlNode correspondent to the item.
+ */
+xmlNode
+*rss_source_get_xml (RssSource *rss_source)
+{
+       RssSourcePrivate *priv = RSSSOURCE_GET_PRIVATE (rss_source);
+
+       xmlNode *xnode = xmlNewNode (NULL, (const xmlChar *)"source");
+
+       xmlAddChild (xnode, xmlNewText ((const xmlChar *)priv->title));
+
+       xmlSetProp (xnode, (const xmlChar *)"url", (const xmlChar *)priv->url);
+
+       return xnode;
+}
+
+static void
+rss_source_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       RssSource *rsss = RSSSOURCE (object);
+
+       RssSourcePrivate *priv = RSSSOURCE_GET_PRIVATE (rsss);
+
+       switch (property_id)
+               {
+                       case PROP_TITLE:
+                               priv->title = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_URL:
+                               priv->url = g_strdup (g_value_get_string (value));
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+rss_source_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       RssSource *rsss = RSSSOURCE (object);
+
+       RssSourcePrivate *priv = RSSSOURCE_GET_PRIVATE (rsss);
+
+       switch (property_id)
+               {
+                       case PROP_TITLE:
+                               g_value_set_string (value, priv->title);
+                               break;
+
+                       case PROP_URL:
+                               g_value_set_string (value, priv->url);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/rsssource.h b/src/rsssource.h
new file mode 100644 (file)
index 0000000..b66315a
--- /dev/null
@@ -0,0 +1,63 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __RSSSOURCE_H__
+#define __RSSSOURCE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+G_BEGIN_DECLS
+
+
+#define TYPE_RSSSOURCE                 (rss_cloud_get_type ())
+#define RSSSOURCE(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RSSSOURCE, RssSource))
+#define RSSSOURCE_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RSSSOURCE, RssSourceClass))
+#define IS_RSSSOURCE(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RSSSOURCE))
+#define IS_RSSSOURCE_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RSSSOURCE))
+#define RSSSOURCE_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RSSSOURCE, RssSourceClass))
+
+
+typedef struct _RssSource RssSource;
+typedef struct _RssSourceClass RssSourceClass;
+
+struct _RssSource
+       {
+               GObject parent;
+       };
+
+struct _RssSourceClass
+       {
+               GObjectClass parent_class;
+       };
+
+GType rss_source_get_type (void) G_GNUC_CONST;
+
+RssSource *rss_source_new (const gchar *title, const gchar *url);
+RssSource *rss_source_new_from_xml (xmlNode *xnode);
+
+xmlNode *rss_source_get_xml (RssSource *rss_source);
+
+
+G_END_DECLS
+
+#endif /* __RSSSOURCE_H__ */
diff --git a/src/rsstextinput.c b/src/rsstextinput.c
new file mode 100644 (file)
index 0000000..0e7c39a
--- /dev/null
@@ -0,0 +1,317 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#include <time.h>
+
+#include <libxml/tree.h>
+
+#include "rsstextinput.h"
+
+enum
+{
+       PROP_0,
+       PROP_TITLE,
+       PROP_DESCRIPTION,
+       PROP_NAME,
+       PROP_LINK
+};
+
+static void rss_text_input_class_init (RssTextInputClass *klass);
+static void rss_text_input_init (RssTextInput *rss);
+
+static void rss_text_input_set_property (GObject *object,
+                                         guint property_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec);
+static void rss_text_input_get_property (GObject *object,
+                                         guint property_id,
+                                         GValue *value,
+                                         GParamSpec *pspec);
+
+#define RSSTEXTINPUT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RSSTEXTINPUT, RssTextInputPrivate))
+
+typedef struct _RssTextInputPrivate RssTextInputPrivate;
+struct _RssTextInputPrivate
+       {
+               gchar *title,
+                     *description,
+                     *name,
+                     *link;
+       };
+
+GType
+rss_text_input_get_type (void)
+{
+       static GType rss_text_input_type = 0;
+
+       if (!rss_text_input_type)
+               {
+                       static const GTypeInfo rss_text_input_info =
+                       {
+                               sizeof (RssTextInputClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc) rss_text_input_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof (RssTextInput),
+                               0,      /* n_preallocs */
+                               (GInstanceInitFunc) rss_text_input_init,
+                               NULL
+                       };
+
+                       rss_text_input_type = g_type_register_static (G_TYPE_OBJECT, "RssTextInput",
+                                                                     &rss_text_input_info, 0);
+               }
+
+       return rss_text_input_type;
+}
+
+static void
+rss_text_input_class_init (RssTextInputClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (object_class, sizeof (RssTextInputPrivate));
+
+       object_class->set_property = rss_text_input_set_property;
+       object_class->get_property = rss_text_input_get_property;
+
+       g_object_class_install_property (object_class, PROP_TITLE,
+                                        g_param_spec_string ("title",
+                                                             "Title",
+                                                             "The label of the Submit button in the text input area",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_DESCRIPTION,
+                                        g_param_spec_string ("description",
+                                                             "Description",
+                                                             "Explains the text input area",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_NAME,
+                                        g_param_spec_string ("name",
+                                                             "Name",
+                                                             "The name of the text object in the text input area",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (object_class, PROP_LINK,
+                                        g_param_spec_string ("link",
+                                                             "Link",
+                                                             "The URL of the CGI script that processes text input requests",
+                                                             "",
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+rss_text_input_init (RssTextInput *rss)
+{
+}
+
+/**
+ * rss_text_input_new:
+ * @title:
+ * @description:
+ * @name:
+ * @link:
+ *
+ * Returns: the newly created #RssTextInput object.
+ */
+RssTextInput
+*rss_text_input_new (const gchar *title,
+                     const gchar *description,
+                     const gchar *name,
+                     const gchar *link)
+{
+       g_return_val_if_fail (title != NULL, NULL);
+       g_return_val_if_fail (description!= NULL, NULL);
+       g_return_val_if_fail (name!= NULL, NULL);
+       g_return_val_if_fail (link != NULL, NULL);
+
+       gchar *_title = g_strstrip (g_strdup (title)),
+             *_description = g_strstrip (g_strdup (description)),
+             *_name = g_strstrip (g_strdup (name)),
+             *_link = g_strstrip (g_strdup (link));
+
+       if (strcmp (_title, "") == 0)
+               {
+                       g_critical ("rss_text_input_new: title cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_description, "") == 0)
+               {
+                       g_critical ("rss_text_input_new: description cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_name, "") == 0)
+               {
+                       g_critical ("rss_text_input_new: name cannot be an empty string");
+                       return NULL;
+               }
+       if (strcmp (_link, "") == 0)
+               {
+                       g_critical ("rss_text_input_new: link cannot be an empty string");
+                       return NULL;
+               }
+
+       RssTextInput *rssti = RSSTEXTINPUT (g_object_new (rss_text_input_get_type (), NULL));
+
+       g_object_set (G_OBJECT (rssti),
+                     "title", _title,
+                     "description", _description,
+                     "name", _name,
+                     "link", _link,
+                     NULL);
+
+       return rssti;
+}
+
+/**
+ * rss_text_input_new_from_xml:
+ * @xnode: an #xmlNode.
+ *
+ */
+RssTextInput
+*rss_text_input_new_from_xml (xmlNode *xnode)
+{
+       RssTextInput *rssti = rss_text_input_new ("title", "description", "name", "link");
+       gboolean title = FALSE, description = FALSE, name = FALSE, link = FALSE;
+
+       xmlNode *cur = xnode->xmlChildrenNode;
+       while (cur != NULL)
+               {
+                       if (xmlStrcmp (cur->name, (const xmlChar *)"title") == 0)
+                               {
+                                       title = TRUE;
+                                       g_object_set (G_OBJECT (rssti),
+                                                     "title", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"description") == 0)
+                               {
+                                       description = TRUE;
+                                       g_object_set (G_OBJECT (rssti),
+                                                     "description", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"name") == 0)
+                               {
+                                       name = TRUE;
+                                       g_object_set (G_OBJECT (rssti),
+                                                     "name", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+                       else if (xmlStrcmp (cur->name, (const xmlChar *)"link") == 0)
+                               {
+                                       link = TRUE;
+                                       g_object_set (G_OBJECT (rssti),
+                                                     "link", (gchar *)xmlNodeGetContent (cur),
+                                                     NULL);
+                               }
+
+                       cur = cur->next;
+               }
+
+       return (!title || !description || !name || !link ? NULL : rssti);
+}
+
+/**
+ * rss_text_input_get_xml:
+ * @rss_text_input: a #RssTextInput object
+ *
+ * Returns: the #xmlNode correspondent to the item.
+ */
+xmlNode
+*rss_text_input_get_xml (RssTextInput *rss_text_input)
+{
+       RssTextInputPrivate *priv = RSSTEXTINPUT_GET_PRIVATE (rss_text_input);
+
+       xmlNode *xnode = xmlNewNode (NULL, (const xmlChar *)"textInput");
+
+       xmlNewTextChild (xnode, NULL, (const xmlChar *)"title", (const xmlChar *)priv->title);
+       xmlNewTextChild (xnode, NULL, (const xmlChar *)"description", (const xmlChar *)priv->description);
+       xmlNewTextChild (xnode, NULL, (const xmlChar *)"name", (const xmlChar *)priv->name);
+       xmlNewTextChild (xnode, NULL, (const xmlChar *)"link", (const xmlChar *)priv->link);
+
+       return xnode;
+}
+
+static void
+rss_text_input_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       RssTextInput *rssti = RSSTEXTINPUT (object);
+
+       RssTextInputPrivate *priv = RSSTEXTINPUT_GET_PRIVATE (rssti);
+
+       switch (property_id)
+               {
+                       case PROP_TITLE:
+                               priv->title = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_DESCRIPTION:
+                               priv->description = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_NAME:
+                               priv->name = g_strdup (g_value_get_string (value));
+                               break;
+
+                       case PROP_LINK:
+                               priv->link = g_strdup (g_value_get_string (value));
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
+
+static void
+rss_text_input_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       RssTextInput *rssti = RSSTEXTINPUT (object);
+
+       RssTextInputPrivate *priv = RSSTEXTINPUT_GET_PRIVATE (rssti);
+
+       switch (property_id)
+               {
+                       case PROP_TITLE:
+                               g_value_set_string (value, priv->title);
+                               break;
+
+                       case PROP_DESCRIPTION:
+                               g_value_set_string (value, priv->description);
+                               break;
+
+                       case PROP_NAME:
+                               g_value_set_string (value, priv->name);
+                               break;
+
+                       case PROP_LINK:
+                               g_value_set_string (value, priv->link);
+                               break;
+
+                       default:
+                               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                               break;
+               }
+}
diff --git a/src/rsstextinput.h b/src/rsstextinput.h
new file mode 100644 (file)
index 0000000..b5b352b
--- /dev/null
@@ -0,0 +1,66 @@
+/* libgfeed
+ *
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Andrea Zagli <azagli@inwind.it>
+ */
+
+#ifndef __RSSTEXTINPUT_H__
+#define __RSSTEXTINPUT_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+G_BEGIN_DECLS
+
+
+#define TYPE_RSSTEXTINPUT                 (rss_text_input_get_type ())
+#define RSSTEXTINPUT(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RSSTEXTINPUT, RssTextInput))
+#define RSSTEXTINPUT_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RSSTEXTINPUT, RssTextInputClass))
+#define IS_RSSTEXTINPUT(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RSSTEXTINPUT))
+#define IS_RSSTEXTINPUT_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RSSTEXTINPUT))
+#define RSSTEXTINPUT_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RSSTEXTINPUT, RssTextInputClass))
+
+
+typedef struct _RssTextInput RssTextInput;
+typedef struct _RssTextInputClass RssTextInputClass;
+
+struct _RssTextInput
+       {
+               GObject parent;
+       };
+
+struct _RssTextInputClass
+       {
+               GObjectClass parent_class;
+       };
+
+GType rss_text_input_get_type (void) G_GNUC_CONST;
+
+RssTextInput *rss_text_input_new (const gchar *title,
+                                  const gchar *description,
+                                  const gchar *name,
+                                  const gchar *link);
+RssTextInput *rss_text_input_new_from_xml (xmlNode *xnode);
+
+xmlNode *rss_text_input_get_xml (RssTextInput *rss_text_input);
+
+
+G_END_DECLS
+
+#endif /* __RSSTEXTINPUT_H__ */
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644 (file)
index 0000000..e6c06ac
--- /dev/null
@@ -0,0 +1,13 @@
+LIBS = $(GFEED_LIBS)
+
+AM_CPPFLAGS = $(GFEED_CFLAGS) \
+              -I$(top_srcdir)/src
+
+noinst_PROGRAMS = test_rss \
+                  test_rss_load \
+                  test_rss_load_buffer \
+                  test_atom \
+                  test_atom_load \
+                  test_atom_load_buffer
+
+LDADD = $(top_srcdir)/src/libgfeed.la
diff --git a/test/test_atom.c b/test/test_atom.c
new file mode 100644 (file)
index 0000000..d4d1070
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ *  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 <time.h>
+
+#include <gfeed.h>
+
+int
+main (int argc, char **argv)
+{
+       Atom *atom;
+       AtomID *id;
+       AtomText *title;
+       AtomDate *updated;
+       GList *authors = NULL,
+             *entries = NULL;
+       AtomEntry *entry;
+       AtomContent *content;
+       time_t timet;
+       struct tm tm;
+       xmlDoc *xdoc;
+
+       g_type_init ();
+
+       id = atom_id_new ("http://foo.mydomain.com/");
+       title = atom_text_new (ATOM_TEXT_XHTML, "dive into mark");
+       g_object_set (G_OBJECT (title),
+                     "lang", "it",
+                     NULL);
+
+       timet = time (NULL);
+
+       gmtime_r ((const time_t *)&timet, (struct tm *)&tm);
+       tm.tm_sec = 0;
+       tm.tm_min = 0;
+       tm.tm_hour = 0;
+
+       updated = atom_date_new (tm);
+
+       atom = atom_new (id, title, updated);
+
+       authors = g_list_append (authors, (gpointer)atom_person_new ("Andrea Zagli"));
+       g_object_set (G_OBJECT (authors->data),
+                     "uri", "http://saettaz.altervista.org            ",
+                     "email", "       azagli@inwind.it",
+                     NULL);
+
+       g_object_set (G_OBJECT (atom),
+                     "author", authors,
+                     NULL);
+
+       content = atom_content_new (ATOM_CONTENT_XHTML);
+       g_object_set (G_OBJECT (content),
+                     "text", "content's text",
+                     NULL);
+
+       entries = g_list_append (entries, (gpointer)atom_entry_new (
+                                                      atom_id_new ("http://foo.mydomain.com/e1.html"),
+                                                      atom_text_new (ATOM_TEXT_TEXT, "the title"),
+                                                      updated));
+       g_object_set (G_OBJECT (entries->data),
+                     "content", content,
+                     NULL);
+
+       entry = atom_entry_new (atom_id_new ("http://foo.mydomain.com/e2.html"),
+                               atom_text_new (ATOM_TEXT_TEXT, "the second entry"),
+                               updated);
+
+       g_object_set (G_OBJECT (entry),
+                     "content", content,
+                     NULL);
+
+       entries = g_list_append (entries, (gpointer)entry);
+
+       g_object_set (G_OBJECT (atom),
+                     "entry", entries,
+                     NULL);
+
+       xdoc = atom_get_xml_doc (atom);
+       xmlSaveFormatFileEnc ("./test_atom.xml", xdoc, "iso-8859-1", 2);
+
+       atom_save_file (atom, "./test_atom_gfeed.xml");
+
+       return 0;
+}
diff --git a/test/test_atom_load.c b/test/test_atom_load.c
new file mode 100644 (file)
index 0000000..2daeddf
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ *  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 <time.h>
+
+#include <gfeed.h>
+
+int
+main (int argc, char **argv)
+{
+       Atom *atom;
+       xmlDoc *xdoc;
+
+       g_type_init ();
+
+       atom = atom_new_from_file (argv[1]);
+
+       if (atom != NULL)
+               {
+                       xdoc = atom_get_xml_doc (atom);
+                       if (xdoc != NULL)
+                               {
+                                       xmlSaveFormatFileEnc ("./test_atom_load.xml", xdoc, "iso-8859-1", 2);
+                               }
+                       else
+                               {
+                                       g_fprintf (stderr, "xdoc is null\n");
+                               }
+                       
+                       atom_save_file (atom, "./test_atom_load_gfeed.xml");
+               }
+       else
+               {
+                       g_fprintf (stderr, "atom is null\n");
+               }
+
+       return 0;
+}
diff --git a/test/test_atom_load_buffer.c b/test/test_atom_load_buffer.c
new file mode 100644 (file)
index 0000000..78e6466
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ *  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 <gfeed.h>
+
+gchar *
+read_file (const gchar *filename)
+{
+       gchar *ret = "";
+       FILE *fin;
+
+       fin = fopen (filename, "r");
+
+       if (fin != NULL)
+               {
+                       gchar ch;
+
+                       while ((ch = getc (fin)) != EOF)
+                               {
+                                       ret = g_strconcat (ret, g_strdup_printf ("%c", ch), NULL);
+                               }
+               }
+
+       fclose (fin);
+
+       return ret;
+}
+
+int
+main (int argc, char **argv)
+{
+       gchar *buffer;
+       Atom *atom;
+       xmlDoc *xdoc;
+
+       g_type_init ();
+
+       /* reading the file */
+       buffer = read_file (argv[1]);
+
+       atom = atom_new_from_buffer (buffer);
+
+       if (atom != NULL)
+               {
+                       xdoc = atom_get_xml_doc (atom);
+                       if (xdoc != NULL)
+                               {
+                                       xmlSaveFormatFileEnc ("./test_atom_load_buffer.xml", xdoc, "iso-8859-1", 2);
+                               }
+                       else
+                               {
+                                       g_fprintf (stderr, "xdoc is null\n");
+                               }
+                       
+                       atom_save_file (atom, "./test_atom_load_buffer_gfeed.xml");
+               }
+       else
+               {
+                       g_fprintf (stderr, "atom is null\n");
+               }
+
+       return 0;
+}
diff --git a/test/test_rss.c b/test/test_rss.c
new file mode 100644 (file)
index 0000000..ee20909
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ *  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 <time.h>
+
+#include <gfeed.h>
+
+int
+main (int argc, char **argv)
+{
+       Rss *rss;
+       RssChannel *rssc;
+       RssCategory *rssca;
+       RssCloud *rsscl;
+       RssImage *rssi;
+       RssTextInput *rssti;
+       RssChannelItem *rssci;
+       time_t timet;
+       struct tm pubDate, lastBuildDate;
+       xmlDoc *xdoc;
+       guint skipDays, skipHours;
+
+       g_type_init ();
+
+       rss = rss_new ();
+
+       rssc = rss_channel_new ("Channel",
+                               "http://www.channels.org/link1.html",
+                               "First channel - Description");
+
+       if (rssc == NULL) return 0;
+
+       g_object_set (G_OBJECT (rss),
+                     "channel", rssc,
+                     NULL);
+
+       rssca = rss_category_new ("Comics");
+       rss_channel_add_category (rssc, rssca);
+       
+       rssca = rss_category_new ("Horror");
+       g_object_set (G_OBJECT (rssca),
+                     "domain", "the domain",
+                     NULL);
+       rss_channel_add_category (rssc, rssca);
+
+       timet = time (NULL);
+
+       gmtime_r ((const time_t *)&timet, (struct tm *)&pubDate);
+       pubDate.tm_sec = 0;
+       pubDate.tm_min = 0;
+       pubDate.tm_hour = 0;
+
+       gmtime_r ((const time_t *)&timet, (struct tm *)&lastBuildDate);
+
+       rsscl = rss_cloud_new ("radio.xmlstoragesystem.com", 80, "/RPC2", "xmlStorageSystem.rssPleaseNotify", "xml-rpc");
+       
+       rssi = rss_image_new ("http://www.image.com/01.png", "the title", "http://www.channels.org/link1.html");
+
+       rssti = rss_text_input_new ("The text input's title", "a short description", "ti1", "http://www.google.com");
+
+       skipDays = RSSCHANNEL_DAY_MONDAY | RSSCHANNEL_DAY_TUESDAY | RSSCHANNEL_DAY_WEDNESDAY |
+                  RSSCHANNEL_DAY_THURSDAY | RSSCHANNEL_DAY_FRIDAY | RSSCHANNEL_DAY_SATURDAY | RSSCHANNEL_DAY_SUNDAY;
+
+       skipHours = RSSCHANNEL_HOUR_23;
+       
+       g_object_set (G_OBJECT (rssc),
+                     "language", "en",
+                     "copyright", "mine",
+                     "pub-date", &pubDate,
+                     "last-build-date", &lastBuildDate,
+                     "cloud", rsscl,
+                     "image", rssi,
+                     "text-input", rssti,
+                     "skip-days", skipDays,
+                                                               "skip-hours", skipHours,
+                     NULL);
+
+       rssci = rss_channel_item_new ("Title item 1", "with this description");
+
+       rssca = rss_category_new ("Sci-Fi");
+       g_object_set (G_OBJECT (rssca),
+                     "domain", "my domain",
+                     NULL);
+       rss_channel_item_add_category (rssci, rssca);
+
+       g_object_set (G_OBJECT (rssci),
+                     "author", "author@myhouse.it",
+                     "comments", "http://www.google.com",
+                     NULL);
+
+       rss_channel_add_item (rssc, rssci);
+
+       xdoc = rss_get_xml_doc (rss);
+       xmlSaveFormatFileEnc ("./test.xml", xdoc, "iso-8859-1",2);
+
+       rss_save_file (rss, "./test_gfeed.xml");
+
+       return 0;
+}
diff --git a/test/test_rss_load.c b/test/test_rss_load.c
new file mode 100644 (file)
index 0000000..f76ea35
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ *  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 <time.h>
+
+#include <gfeed.h>
+
+int
+main (int argc, char **argv)
+{
+       Rss *rss;
+       xmlDoc *xdoc;
+
+       g_type_init ();
+
+       rss = rss_new_from_file (argv[1]);
+
+       if (rss != NULL)
+               {
+                       xdoc = rss_get_xml_doc (rss);
+                       if (xdoc != NULL)
+                               {
+                                       xmlSaveFormatFileEnc ("./test_load.xml", xdoc, "iso-8859-1", 2);
+                               }
+                       else
+                               {
+                                       g_fprintf (stderr, "xdoc is null\n");
+                               }
+                       
+                       rss_save_file (rss, "./test_load_gfeed.xml");
+               }
+       else
+               {
+                       g_fprintf (stderr, "rss is null\n");
+               }
+
+       return 0;
+}
diff --git a/test/test_rss_load_buffer.c b/test/test_rss_load_buffer.c
new file mode 100644 (file)
index 0000000..9a8f57b
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2005-2006 Andrea Zagli <azagli@inwind.it>
+ *
+ *  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 <gfeed.h>
+
+gchar *
+read_file (const gchar *filename)
+{
+       gchar *ret = "";
+       FILE *fin;
+
+       fin = fopen (filename, "r");
+
+       if (fin != NULL)
+               {
+                       gchar ch;
+
+                       while ((ch = getc (fin)) != EOF)
+                               {
+                                       ret = g_strconcat (ret, g_strdup_printf ("%c", ch), NULL);
+                               }
+               }
+
+       fclose (fin);
+
+       return ret;
+}
+
+int
+main (int argc, char **argv)
+{
+       Rss *rss;
+       xmlDoc *xdoc;
+       gchar *buffer;
+
+       g_type_init ();
+
+       /* reading the file */
+       buffer = read_file (argv[1]);
+
+       rss = rss_new_from_buffer (buffer);
+
+       if (rss != NULL)
+               {
+                       xdoc = rss_get_xml_doc (rss);
+                       if (xdoc != NULL)
+                               {
+                                       xmlSaveFormatFileEnc ("./test_load_buffer.xml", xdoc, "iso-8859-1", 2);
+                               }
+                       else
+                               {
+                                       g_fprintf (stderr, "xdoc is null\n");
+                               }
+                       
+                       rss_save_file (rss, "./test_load_gfeed_buffer.xml");
+               }
+       else
+               {
+                       g_fprintf (stderr, "rss is null\n");
+               }
+
+       return 0;
+}