Main Page | Data Structures | Directories | File List | Data Fields | Globals

mrss_write.c

Go to the documentation of this file.
00001 /* mRss - Copyright (C) 2005 bakunin - Andrea Marchesini 
00002  *                                <bakunin@autistici.org>
00003  *
00004  * This source code is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Public License as published 
00006  * by the Free Software Foundation; either version 2 of the License,
00007  * or (at your option) any later version.
00008  *
00009  * This source code is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00012  * Please refer to the GNU Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Public License along with
00015  * this source code; if not, write to:
00016  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 #ifdef HAVE_CONFIG_H
00020 #include <config.h>
00021 #else
00022 # error Use configure; make; make install
00023 #endif
00024 
00025 #include "mrss.h"
00026 #include "mrss_internal.h"
00027 
00028 static void __mrss_write_string(void (*func)(void *, char *,...), void *obj, char *str) {
00029   int i;
00030   int len;
00031   char buf[1024];
00032   int j;
00033 
00034 #define __NXML_CHECK_BUF \
00035            if(j==sizeof(buf)-1) { buf[j]=0; func(obj, "%s",buf); j=0; }
00036 
00037   if (!str)
00038     return;
00039 
00040   len = strlen (str);
00041 
00042   for (j = i = 0; i < len; i++)
00043     {
00044       if (str[i] == '\r')
00045         continue;
00046 
00047       else if (str[i] == '<')
00048         {
00049           buf[j++] = '&';
00050           __NXML_CHECK_BUF;
00051           buf[j++] = 'l';
00052           __NXML_CHECK_BUF;
00053           buf[j++] = 't';
00054           __NXML_CHECK_BUF;
00055           buf[j++] = ';';
00056           __NXML_CHECK_BUF;
00057         }
00058 
00059       else if (str[i] == '>')
00060         {
00061           buf[j++] = '&';
00062           __NXML_CHECK_BUF;
00063           buf[j++] = 'g';
00064           __NXML_CHECK_BUF;
00065           buf[j++] = 't';
00066           __NXML_CHECK_BUF;
00067           buf[j++] = ';';
00068           __NXML_CHECK_BUF;
00069         }
00070 
00071       else if (str[i] == '&')
00072         {
00073           buf[j++] = '&';
00074           __NXML_CHECK_BUF;
00075           buf[j++] = 'a';
00076           __NXML_CHECK_BUF;
00077           buf[j++] = 'm';
00078           __NXML_CHECK_BUF;
00079           buf[j++] = 'p';
00080           __NXML_CHECK_BUF;
00081           buf[j++] = ';';
00082           __NXML_CHECK_BUF;
00083         }
00084 
00085       else if (str[i] == '\'')
00086         {
00087           buf[j++] = '&';
00088           __NXML_CHECK_BUF;
00089           buf[j++] = 'a';
00090           __NXML_CHECK_BUF;
00091           buf[j++] = 'p';
00092           __NXML_CHECK_BUF;
00093           buf[j++] = 'o';
00094           __NXML_CHECK_BUF;
00095           buf[j++] = 's';
00096           __NXML_CHECK_BUF;
00097           buf[j++] = ';';
00098           __NXML_CHECK_BUF;
00099         }
00100 
00101       else if (str[i] == '\'')
00102         {
00103           buf[j++] = '&';
00104           __NXML_CHECK_BUF;
00105           buf[j++] = 'q';
00106           __NXML_CHECK_BUF;
00107           buf[j++] = 'u';
00108           __NXML_CHECK_BUF;
00109           buf[j++] = 'o';
00110           __NXML_CHECK_BUF;
00111           buf[j++] = 't';
00112           __NXML_CHECK_BUF;
00113           buf[j++] = ';';
00114           __NXML_CHECK_BUF;
00115         }
00116 
00117       else
00118         {
00119           buf[j++] = str[i];
00120           __NXML_CHECK_BUF;
00121         }
00122     }
00123 
00124   if (j)
00125     {
00126       buf[j] = 0;
00127       func (obj, "%s", buf);
00128       j = 0;
00129     }
00130 }
00131 
00132 static mrss_error_t
00133 __mrss_write_real (mrss_t * mrss, void (*func) (void *, char *, ...),
00134                    void *obj)
00135 {
00136   mrss_item_t *item;
00137   mrss_category_t *category;
00138 
00139   func (obj, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
00140         "<rss version=\"");
00141 
00142   switch (mrss->version)
00143     {
00144     case MRSS_VERSION_0_91:
00145       func (obj, "0.91");
00146       break;
00147 
00148     case MRSS_VERSION_0_92:
00149       func (obj, "0.92");
00150       break;
00151 
00152     case MRSS_VERSION_2_0:
00153       func (obj, "2.0");
00154       break;
00155     }
00156 
00157   func (obj, "\">\n");
00158 
00159   func (obj, "  <channel>\n");
00160 
00161   if (mrss->title)
00162     {
00163       func (obj, "    <title>");
00164       __mrss_write_string (func, obj, mrss->title);
00165       func (obj, "</title>\n");
00166     }
00167 
00168   if (mrss->description)
00169     {
00170       func (obj, "    <description>");
00171       __mrss_write_string (func, obj, mrss->description);
00172       func (obj, "</description>\n");
00173     }
00174 
00175   if (mrss->link)
00176     {
00177       func (obj, "    <link>");
00178       __mrss_write_string (func, obj, mrss->link);
00179       func (obj, "</link>\n");
00180     }
00181 
00182   if (mrss->language)
00183     {
00184       func (obj, "    <language>");
00185       __mrss_write_string (func, obj, mrss->language);
00186       func (obj, "</language>\n");
00187     }
00188 
00189   if (mrss->rating)
00190     {
00191       func (obj, "    <rating>");
00192       __mrss_write_string (func, obj, mrss->rating);
00193       func (obj, "</rating>\n");
00194     }
00195 
00196   if (mrss->copyright)
00197     {
00198       func (obj, "    <copyright>");
00199       __mrss_write_string (func, obj, mrss->copyright);
00200       func (obj, "</copyright>\n");
00201     }
00202 
00203   if (mrss->pubDate)
00204     {
00205       func (obj, "    <pubDate>");
00206       __mrss_write_string (func, obj, mrss->pubDate);
00207       func (obj, "</pubDate>\n");
00208     }
00209 
00210   if (mrss->lastBuildDate)
00211     {
00212       func (obj, "    <lastBuildDate>");
00213       __mrss_write_string (func, obj, mrss->lastBuildDate);
00214       func (obj, "</lastBuildDate>\n");
00215     }
00216 
00217   if (mrss->docs)
00218     {
00219       func (obj, "    <docs>");
00220       __mrss_write_string (func, obj, mrss->docs);
00221       func (obj, "</docs>\n");
00222     }
00223 
00224   if (mrss->managingeditor)
00225     {
00226       func (obj, "    <managingeditor>");
00227       __mrss_write_string (func, obj, mrss->managingeditor);
00228       func (obj, "</managingeditor>\n");
00229     }
00230 
00231   if (mrss->webMaster)
00232     {
00233       func (obj, "    <webMaster>");
00234       __mrss_write_string (func, obj, mrss->webMaster);
00235       func (obj, "</webMaster>\n");
00236     }
00237 
00238   if (mrss->version == MRSS_VERSION_2_0)
00239     {
00240       if (mrss->generator)
00241         {
00242           func (obj, "    <generator>");
00243           __mrss_write_string (func, obj, mrss->generator);
00244           func (obj, "</generator>\n");
00245         }
00246 
00247       if (mrss->ttl)
00248         func (obj, "    <ttl>%d</ttl>\n", mrss->ttl);
00249     }
00250 
00251   if (mrss->image_title || mrss->image_url || mrss->image_link
00252       || mrss->image_width || mrss->image_height || mrss->description)
00253     {
00254 
00255       func (obj, "    <image>\n");
00256 
00257       if (mrss->image_title)
00258         {
00259           func (obj, "      <title>");
00260           __mrss_write_string (func, obj, mrss->image_title);
00261           func (obj, "</title>\n");
00262         }
00263 
00264       if (mrss->image_url)
00265         {
00266           func (obj, "      <url>");
00267           __mrss_write_string (func, obj, mrss->image_url);
00268           func (obj, "</url>\n");
00269         }
00270 
00271       if (mrss->image_link)
00272         {
00273           func (obj, "      <link>");
00274           __mrss_write_string (func, obj, mrss->image_link);
00275           func (obj, "</link>\n");
00276         }
00277 
00278       if (mrss->image_width)
00279         func (obj, "      <width>%d</width>\n", mrss->image_width);
00280 
00281       if (mrss->image_height)
00282         func (obj, "      <height>%d</height>\n", mrss->image_height);
00283 
00284       if (mrss->image_description)
00285         {
00286           func (obj, "      <description>");
00287           __mrss_write_string (func, obj, mrss->image_description);
00288           func (obj, "</description>\n");
00289         }
00290 
00291       func (obj, "    </image>\n");
00292     }
00293 
00294   if (mrss->textinput_title || mrss->textinput_description
00295       || mrss->textinput_name || mrss->textinput_link)
00296     {
00297 
00298       func (obj, "    <textinput>\n");
00299 
00300       if (mrss->textinput_title)
00301         {
00302           func (obj, "      <title>");
00303           __mrss_write_string (func, obj, mrss->textinput_title);
00304           func (obj, "</title>\n");
00305         }
00306 
00307       if (mrss->textinput_description)
00308         {
00309           func (obj, "      <description>");
00310           __mrss_write_string (func, obj, mrss->textinput_description);
00311           func (obj, "</description>\n");
00312         }
00313 
00314       if (mrss->textinput_name)
00315         {
00316           func (obj, "      <name>");
00317           __mrss_write_string (func, obj, mrss->textinput_name);
00318           func (obj, "</name>\n");
00319         }
00320 
00321       if (mrss->textinput_link)
00322         {
00323           func (obj, "      <link>");
00324           __mrss_write_string (func, obj, mrss->textinput_link);
00325           func (obj, "</link>\n");
00326         }
00327 
00328       func (obj, "    </textinput>\n");
00329     }
00330 
00331   if ((mrss->version == MRSS_VERSION_0_92
00332        || mrss->version == MRSS_VERSION_2_0) && mrss->cloud)
00333     {
00334       func (obj, "    <cloud");
00335 
00336       if (mrss->cloud_domain)
00337         {
00338           func (obj, " domain=\"");
00339           __mrss_write_string (func, obj, mrss->cloud_domain);
00340           func (obj, "\"");
00341         }
00342 
00343       if (mrss->cloud_port)
00344         func (obj, " port=\"%d\"", mrss->cloud_port);
00345 
00346       if (mrss->cloud_path)
00347         {
00348           func (obj, " path=\"");
00349           __mrss_write_string (func, obj, mrss->cloud_path);
00350           func (obj, "\"");
00351         }
00352 
00353       if (mrss->cloud_registerProcedure)
00354         {
00355           func (obj, " registerProcedure=\"");
00356           __mrss_write_string (func, obj, mrss->cloud_registerProcedure);
00357           func (obj, "\"");
00358         }
00359 
00360       if (mrss->cloud_protocol)
00361         {
00362           func (obj, " protocol=\"");
00363           __mrss_write_string (func, obj, mrss->cloud_protocol);
00364           func (obj, "\"");
00365         }
00366 
00367       func (obj, ">%s</cloud>\n", mrss->cloud);
00368     }
00369 
00370   if (mrss->skipHours)
00371     {
00372       mrss_hour_t *hour;
00373 
00374       func (obj, "    <skipHours>\n");
00375 
00376       hour = mrss->skipHours;
00377       while (hour)
00378         {
00379           func (obj, "      <hour>");
00380           __mrss_write_string (func, obj, hour->hour);
00381           func (obj, "</hour>\n");
00382 
00383           hour = hour->next;
00384         }
00385 
00386       func (obj, "    </skipHours>\n");
00387     }
00388 
00389   if (mrss->skipDays)
00390     {
00391       mrss_day_t *day;
00392 
00393       func (obj, "    <skipDays>\n");
00394 
00395       day = mrss->skipDays;
00396       while (day)
00397         {
00398           func (obj, "      <day>");
00399           __mrss_write_string (func, obj, day->day);
00400           func (obj, "</day>\n");
00401           day = day->next;
00402         }
00403 
00404       func (obj, "    </skipDays>\n");
00405     }
00406 
00407   if ((mrss->version == MRSS_VERSION_0_92
00408        || mrss->version == MRSS_VERSION_2_0) && mrss->category)
00409     {
00410       category = mrss->category;
00411       while (category)
00412         {
00413           func (obj, "    <category");
00414 
00415           if (category->domain)
00416             {
00417               func (obj, " domain=\"");
00418               __mrss_write_string (func, obj, category->domain);
00419               func (obj, "\"");
00420             }
00421 
00422           func (obj, ">");
00423           __mrss_write_string (func, obj, category->category);
00424           func (obj, "</category>\n");
00425 
00426           category = category->next;
00427         }
00428     }
00429 
00430   item = mrss->item;
00431   while (item)
00432     {
00433       func (obj, "    <item>\n");
00434 
00435       if (item->title)
00436         {
00437           func (obj, "      <title>");
00438           __mrss_write_string (func, obj, item->title);
00439           func (obj, "</title>\n");
00440         }
00441 
00442       if (item->link)
00443         {
00444           func (obj, "      <link>");
00445           __mrss_write_string (func, obj, item->link);
00446           func (obj, "</link>\n");
00447         }
00448 
00449       if (item->description)
00450         {
00451           func (obj, "      <description>");
00452           __mrss_write_string (func, obj, item->description);
00453           func (obj, "</description>\n");
00454         }
00455 
00456       if (mrss->version == MRSS_VERSION_2_0)
00457         {
00458           if (item->author)
00459             {
00460               func (obj, "      <author>");
00461               __mrss_write_string (func, obj, item->author);
00462               func (obj, "</author>\n");
00463             }
00464 
00465           if (item->comments)
00466             {
00467               func (obj, "      <comments>");
00468               __mrss_write_string (func, obj, item->comments);
00469               func (obj, "</comments>\n");
00470             }
00471 
00472           if (item->pubDate)
00473             {
00474               func (obj, "      <pubDate>");
00475               __mrss_write_string (func, obj, item->pubDate);
00476               func (obj, "</pubDate>\n");
00477             }
00478 
00479           if (item->guid)
00480             {
00481               func (obj, "      <guid isPermaLink=\"%s\">");
00482               __mrss_write_string (func, obj, item->guid);
00483               func (obj, "</guid>\n");
00484             }
00485 
00486         }
00487 
00488       if (mrss->version == MRSS_VERSION_2_0
00489           || mrss->version == MRSS_VERSION_0_92)
00490         {
00491           if (item->source)
00492             {
00493               func (obj, "      <source");
00494 
00495               if (item->source_url)
00496                 {
00497                   func (obj, " url=\"");
00498                   __mrss_write_string (func, obj, item->source_url);
00499                   func (obj, "\"");
00500                 }
00501 
00502               func (obj, ">");
00503               __mrss_write_string (func, obj, item->source);
00504               func (obj, "</source>\n");
00505             }
00506 
00507           if (item->enclosure)
00508             {
00509               func (obj, "      <enclosure");
00510 
00511               if (item->enclosure_url)
00512                 {
00513                   func (obj, " url=\"");
00514                   __mrss_write_string (func, obj, item->enclosure_url);
00515                   func (obj, "\"");
00516                 }
00517 
00518               if (item->enclosure_length)
00519                 func (obj, " length=\"%d\"", item->enclosure_length);
00520 
00521               if (item->enclosure_type)
00522                 {
00523                   func (obj, " type=\"");
00524                   __mrss_write_string (func, obj, item->enclosure_type);
00525                   func (obj, "\"");
00526                 }
00527 
00528               func (obj, ">");
00529               __mrss_write_string (func, obj, item->enclosure);
00530               func (obj, "</enclosure>\n");
00531 
00532             }
00533 
00534           category = item->category;
00535           while (category)
00536             {
00537               func (obj, "      <category");
00538 
00539               if (category->domain)
00540                 {
00541                   func (obj, " domain=\"");
00542                   __mrss_write_string (func, obj, category->domain);
00543                   func (obj, "\"");
00544                 }
00545 
00546               func (obj, ">");
00547               __mrss_write_string (func, obj, category->category);
00548               func (obj, "</category>\n");
00549 
00550               category = category->next;
00551             }
00552         }
00553 
00554       func (obj, "    </item>\n");
00555 
00556       item = item->next;
00557     }
00558 
00559   func (obj, "  </channel>\n");
00560   func (obj, "</rss>\n");
00561 
00562   return MRSS_OK;
00563 }
00564 
00565 static void
00566 __mrss_file_write (void *obj, char *str, ...)
00567 {
00568   va_list va;
00569 
00570   va_start (va, str);
00571   vfprintf ((FILE *) obj, str, va);
00572   va_end (va);
00573 }
00574 
00575 static void
00576 __mrss_buffer_write (void *obj, char *str, ...)
00577 {
00578   va_list va;
00579   char s[4096];
00580   int len;
00581   char **buffer = (char **) obj;
00582 
00583   va_start (va, str);
00584   len = vsnprintf (s, sizeof (s), str, va);
00585   va_end (va);
00586 
00587   if (!*buffer)
00588     {
00589       if (!(*buffer = (char *) malloc (sizeof (char) * (len + 1))))
00590         return;
00591 
00592       strncpy (*buffer, s, len);
00593     }
00594   else
00595     {
00596       if (!(*buffer = (char *) realloc (*buffer,
00597                                         sizeof (char) * (strlen (*buffer) +
00598                                                          len + 1))))
00599         return;
00600       strncat (*buffer, s, len);
00601     }
00602 }
00603 
00604 /*************************** EXTERNAL FUNCTION ******************************/
00605 
00606 mrss_error_t
00607 mrss_write_file (mrss_t * mrss, char *file)
00608 {
00609   FILE *fl;
00610   mrss_error_t ret;
00611 
00612   if (!mrss || !file)
00613     return MRSS_ERR_DATA;
00614 
00615   if (!(fl = fopen (file, "wb")))
00616     return MRSS_ERR_POSIX;
00617 
00618   ret = __mrss_write_real (mrss, __mrss_file_write, fl);
00619   fclose (fl);
00620 
00621   return ret;
00622 }
00623 
00624 mrss_error_t
00625 mrss_write_buffer (mrss_t * mrss, char **buffer)
00626 {
00627   if (!mrss || !buffer)
00628     return MRSS_ERR_DATA;
00629 
00630   return __mrss_write_real (mrss, __mrss_buffer_write, buffer);
00631 }
00632 
00633 /* EOF */

Generated on Thu Jul 28 12:15:05 2005 for libmrss by  doxygen 1.4.3-20050530