#include "config.h"
#include "RSS20Parser.h"
#include "BlackBerryPlatformAssert.h"
#include "libxml/parser.h"
#include "libxml/xmlwriter.h"
namespace WebCore {
RSS20Parser::RSS20Parser()
{
}
bool RSS20Parser::parseBuffer(const char* buffer, int length, const char* url, const char* encoding)
{
return parseXmlDoc(xmlReadMemory(buffer, length, url, encoding, XML_PARSE_NOBLANKS | XML_PARSE_NONET));
}
bool RSS20Parser::parseXmlDoc(xmlDocPtr doc)
{
if (!doc)
return false;
xmlNode* node = xmlDocGetRootElement(doc);
if (!node) {
xmlFreeDoc(doc);
return false;
}
for (; node; node = node->next) {
String name(reinterpret_cast<const char*>(node->name));
name.makeLower();
if (name == "rss") {
xmlNode* channel = node->children;
if (channel->type == XML_ELEMENT_NODE) {
name = reinterpret_cast<const char*>(channel->name);
name.makeLower();
if (name == "channel")
m_root = parseFeed(channel->children);
}
break;
}
}
xmlFreeDoc(doc);
return m_root;
}
bool RSS20Parser::parseItemBaseAttribute(RSSItemBase* item, const String& name, xmlNode* node)
{
if (name == "link")
item->m_link = textFromXMLNode(node);
else if (name == "title")
item->m_title = textFromXMLNode(node);
else if (name == "description")
item->m_description = textFromXMLNode(node);
else if (name == "pubdate")
item->m_pubDate = textFromXMLNode(node);
else
return false;
return true;
}
RSSItem* RSS20Parser::parseItem(xmlNode* node)
{
BLACKBERRY_ASSERT(node);
RSSItem* item = new RSSItem();
for (; node; node = node->next) {
String name(reinterpret_cast<const char*>(node->name));
name.makeLower();
if (parseItemBaseAttribute(item, name, node))
continue;
if (name == "author")
item->m_author = textFromXMLNode(node);
else if (name == "creator") {
if (item->m_author.isEmpty())
item->m_author = textFromXMLNode(node);
} else if (name == "category")
item->m_categories.append(textFromXMLNode(node));
else if (name == "comments")
item->m_comments = textFromXMLNode(node);
else if (name == "enclosure") {
if (!item->m_enclosure)
item->m_enclosure = parseEnclosure(node);
}
}
return item;
}
RSSFeed* RSS20Parser::parseFeed(xmlNode* node)
{
BLACKBERRY_ASSERT(node);
RSSFeed* feed = new RSSFeed();
for (; node; node = node->next) {
String name(reinterpret_cast<const char*>(node->name));
name.makeLower();
if (parseItemBaseAttribute(feed, name, node))
continue;
if (name == "item")
feed->m_items.append(parseItem(node->children));
else if (name == "language")
feed->m_language = textFromXMLNode(node);
else if (name == "ttl")
feed->m_ttl = textFromXMLNode(node);
}
return feed;
}
RSSEnclosure* RSS20Parser::parseEnclosure(xmlNode* node)
{
BLACKBERRY_ASSERT(node);
RSSEnclosure* enclosure = new RSSEnclosure();
for (xmlAttr* attr = node->properties; attr; attr = attr->next) {
String name(reinterpret_cast<const char*>(attr->name));
name.makeLower();
if (name == "url")
enclosure->m_url = textFromXMLAttr(attr);
else if (name == "type")
enclosure->m_type = textFromXMLAttr(attr);
else if (name == "length")
enclosure->m_length = textFromXMLAttr(attr);
}
return enclosure;
}
}