Author: jbevain
Date: 2007-09-05 05:30:15 -0400 (Wed, 05 Sep 2007)
New Revision: 85340
Modified:
trunk/moon/src/ChangeLog
trunk/moon/src/playlist.cpp
trunk/moon/src/playlist.h
Log:
2007-09-05 Jb Evain <[EMAIL PROTECTED]>
* playlist.cpp, playlist.h: work on playlist parsing.
Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog 2007-09-05 09:28:43 UTC (rev 85339)
+++ trunk/moon/src/ChangeLog 2007-09-05 09:30:15 UTC (rev 85340)
@@ -1,5 +1,9 @@
2007-09-05 Jb Evain <[EMAIL PROTECTED]>
+ * playlist.cpp, playlist.h: work on playlist parsing.
+
+2007-09-05 Jb Evain <[EMAIL PROTECTED]>
+
* xaml.h: export timespan_from_str.
2007-09-05 Jb Evain <[EMAIL PROTECTED]>
Modified: trunk/moon/src/playlist.cpp
===================================================================
--- trunk/moon/src/playlist.cpp 2007-09-05 09:28:43 UTC (rev 85339)
+++ trunk/moon/src/playlist.cpp 2007-09-05 09:30:15 UTC (rev 85340)
@@ -11,14 +11,17 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <expat.h>
+#include <string.h>
#include "playlist.h"
#include "downloader.h"
+#include "xaml.h"
// PlaylistContent
PlaylistContent::PlaylistContent ()
{
+ base = NULL;
title = NULL;
author = NULL;
abstract = NULL;
@@ -26,12 +29,25 @@
PlaylistContent::~PlaylistContent ()
{
+ g_free (base);
g_free (title);
g_free (author);
g_free (abstract);
}
const char *
+PlaylistContent::GetBase ()
+{
+ return base;
+}
+
+void
+PlaylistContent::SetBase (char *base)
+{
+ this->base = base;
+}
+
+const char *
PlaylistContent::GetTitle ()
{
return title;
@@ -116,13 +132,16 @@
this->start_time = start_time;
}
-bool
-playlist_entry_free (List::Node *node, gpointer data)
+gint64
+PlaylistEntry::GetDuration ()
{
- PlaylistEntry *entry = dynamic_cast<PlaylistEntry *> (node);
- delete entry;
+ return duration;
+}
- return true;
+void
+PlaylistEntry::SetDuration (gint64 duration)
+{
+ this->duration = duration;
}
// Playlist
@@ -130,14 +149,13 @@
Playlist::Playlist (MediaElement *element, char *source_name)
: MediaSource (element, source_name)
{
- items = new List ();
+ entries = new List ();
}
Playlist::~Playlist ()
{
- items->ForEach (playlist_entry_free, NULL);
-
- delete items;
+ entries->Clear (true);
+ delete entries;
}
bool
@@ -162,6 +180,12 @@
return false;
}
+void
+Playlist::AddEntry (PlaylistEntry *entry)
+{
+ entries->Append (entry);
+}
+
bool
Playlist::Parse ()
{
@@ -173,7 +197,8 @@
return false;
PlaylistParser *parser = new PlaylistParser (this);
- parser->Parse (text, len);
+ if (!parser->Parse (text, len))
+ error = true;
delete parser;
g_free (text);
@@ -186,43 +211,178 @@
PlaylistParser::PlaylistParser (Playlist *playlist)
{
this->playlist = playlist;
+ entry = NULL;
parser = XML_ParserCreate (NULL);
+ kind_stack = new List ();
+ PushCurrentKind (Root);
+ XML_SetUserData (parser, this);
XML_SetElementHandler (parser, on_start_element, on_end_element);
XML_SetCharacterDataHandler (parser, on_text);
}
PlaylistParser::~PlaylistParser ()
{
+ kind_stack->Clear (true);
+ delete kind_stack;
XML_ParserFree (parser);
-
- g_free (base);
}
void
PlaylistParser::on_start_element (gpointer user_data, const char *name, const
char **attrs)
{
-// PlaylistParser *parser = reinterpret_cast<PlaylistParser *> (user_data);
+ PlaylistParser *parser = reinterpret_cast<PlaylistParser *> (user_data);
+ PlaylistNodeKind kind;
+ //printf ("on_start_element, name: %s\n", name);
+ if (!strcmp (name, "Abstract")) {
+ kind = Abstract;
+ } else if (!strcmp (name, "ASX")) {
+ kind = Asx;
+ } else if (!strcmp (name, "AUTHOR")) {
+ kind = Author;
+ } else if (!strcmp (name, "BANNER")) {
+ kind = Banner;
+ } else if (!strcmp (name, "BASE")) {
+ kind = Base;
+ } else if (!strcmp (name, "COPYRIGHT")) {
+ kind = Copyright;
+ } else if (!strcmp (name, "DURATION")) {
+ kind = Duration;
+ } else if (!strcmp (name, "ENTRY")) {
+ kind = Entry;
+ } else if (!strcmp (name, "ENTRYREF")) {
+ kind = EntryRef;
+ } else if (!strcmp (name, "LOGURL")) {
+ kind = LogUrl;
+ } else if (!strcmp (name, "MOREINFO")) {
+ kind = MoreInfo;
+ } else if (!strcmp (name, "STARTTIME")) {
+ kind = StartTime;
+ } else if (!strcmp (name, "REF")) {
+ kind = Ref;
+ parser->GetCurrentEntry ()->SetSource (NULL); // get source
from href attribute
+ } else if (!strcmp (name, "TITLE")) {
+ kind = Title;
+ } else {
+ kind = Unknown;
+ }
+
+ parser->PushCurrentKind (kind);
}
void
PlaylistParser::on_end_element (gpointer user_data, const char *name)
{
-// PlaylistParser *parser = reinterpret_cast<PlaylistParser *> (user_data);
+ PlaylistParser *parser = reinterpret_cast<PlaylistParser *> (user_data);
+ parser->PopCurrentKind ();
}
void
-PlaylistParser::on_text (gpointer user_data, const char *text, int len)
+PlaylistParser::on_text (gpointer user_data, const char *data, int len)
{
-// PlaylistParser *parser = reinterpret_cast<PlaylistParser *> (user_data);
+ PlaylistParser *parser = reinterpret_cast<PlaylistParser *> (user_data);
+ //printf ("on_text, text: %s\n", g_strndup (data, len));
+ switch (parser->GetCurrentKind ()) {
+ case Abstract:
+ parser->AssertParentKind (Asx | Entry);
+ parser->GetCurrentContent ()->SetAbstract (g_strndup (data,
len));
+ break;
+ case Author:
+ parser->AssertParentKind (Asx | Entry);
+ parser->GetCurrentContent ()->SetAuthor (g_strndup (data, len));
+ break;
+ case Base:
+ parser->AssertParentKind (Asx | Entry);
+ parser->GetCurrentContent ()->SetBase (g_strndup (data, len));
+ break;
+ case Copyright:
+ parser->AssertParentKind (Asx | Entry);
+ parser->GetCurrentContent ()->SetCopyright (g_strndup (data,
len));
+ break;
+ case Duration:
+ parser->AssertParentKind (Entry);
+ parser->GetCurrentEntry ()->SetDuration (timespan_from_str
(g_strndup (data, len)));
+ break;
+ case Entry:
+ parser->AssertParentKind (Asx);
+ parser->AddEntry ();
+ break;
+ case StartTime:
+ parser->AssertParentKind (Entry);
+ parser->GetCurrentEntry ()->SetStartTime (timespan_from_str
(g_strndup (data, len)));
+ break;
+ case Title:
+ parser->AssertParentKind (Asx | Entry);
+ parser->GetCurrentContent ()->SetTitle (g_strndup (data, len));
+ break;
+ default:
+ break;
+ }
}
-void
+bool
PlaylistParser::Parse (const char *text, int len)
{
if (XML_Parse (parser, text, len, TRUE))
- return;
+ return true;
g_warning ("parsing error: %s\n", XML_ErrorString (XML_GetErrorCode
(parser)));
+ return false;
}
+
+PlaylistContent *
+PlaylistParser::GetCurrentContent ()
+{
+ if (entry != NULL)
+ return entry;
+
+ return playlist;
+}
+
+PlaylistEntry *
+PlaylistParser::GetCurrentEntry ()
+{
+ return entry;
+}
+
+void
+PlaylistParser::AddEntry ()
+{
+ PlaylistEntry *entry = new PlaylistEntry ();
+ playlist->AddEntry (entry);
+ this->entry = entry;
+}
+
+void
+PlaylistParser::PushCurrentKind (PlaylistParser::PlaylistNodeKind kind)
+{
+ kind_stack->Append (new KindNode (kind));
+}
+
+void
+PlaylistParser::PopCurrentKind ()
+{
+ kind_stack->Remove (kind_stack->Last ());
+}
+
+PlaylistParser::PlaylistNodeKind
+PlaylistParser::GetCurrentKind ()
+{
+ KindNode *node = dynamic_cast<KindNode *> (kind_stack->Last ());
+ return node->kind;
+}
+
+PlaylistParser::PlaylistNodeKind
+PlaylistParser::GetParentKind ()
+{
+ KindNode *node = dynamic_cast<KindNode *> (kind_stack->Last ()->prev);
+ return node->kind;
+}
+
+void
+PlaylistParser::AssertParentKind (int kind)
+{
+ printf ("AssertParentKind, current: %d kind %d\n", GetParentKind (),
kind);
+ g_assert (GetParentKind () & kind);
+}
Modified: trunk/moon/src/playlist.h
===================================================================
--- trunk/moon/src/playlist.h 2007-09-05 09:28:43 UTC (rev 85339)
+++ trunk/moon/src/playlist.h 2007-09-05 09:30:15 UTC (rev 85340)
@@ -20,6 +20,7 @@
class PlaylistContent {
private:
+ char *base;
char *title;
char *author;
char *abstract;
@@ -28,6 +29,9 @@
PlaylistContent ();
~PlaylistContent ();
+ const char *GetBase ();
+ void SetBase (char *base);
+
const char *GetTitle ();
void SetTitle (char *title);
@@ -45,6 +49,7 @@
private:
char *source;
gint64 start_time;
+ gint64 duration;
public:
PlaylistEntry ();
~PlaylistEntry ();
@@ -54,35 +59,84 @@
gint64 GetStartTime ();
void SetStartTime (gint64 start_time);
+
+ gint64 GetDuration ();
+ void SetDuration (gint64 duration);
};
class Playlist : public MediaSource, public PlaylistContent {
- List *items; // list of PlaylistEntries
+private:
+ List *entries;
+
+ bool Parse ();
public:
Playlist (MediaElement *element, char *source_name);
virtual ~Playlist ();
virtual bool Open ();
+ void AddEntry (PlaylistEntry *entry);
+
static bool IsPlaylistFile (const char *file_name);
-private:
- bool Parse ();
};
class PlaylistParser {
private:
Playlist *playlist;
+ PlaylistEntry *entry;
XML_Parser parser;
- char *base;
+ enum PlaylistNodeKind {
+ Unknown = 0,
+ Root = 1 << 0,
+ Abstract = 1 << 1,
+ Asx = 1 << 2,
+ Author = 1 << 3,
+ Banner = 1 << 4,
+ Base = 1 << 5,
+ Copyright = 1 << 6,
+ Duration = 1 << 7,
+ Entry = 1 << 8,
+ EntryRef = 1 << 9,
+ LogUrl = 1 << 10,
+ MoreInfo = 1 << 11,
+ Ref = 1 << 12,
+ StartTime = 1 << 13,
+ Title = 1 << 14,
+ };
+
+ class KindNode : public List::Node {
+ public:
+ PlaylistNodeKind kind;
+
+ KindNode (PlaylistNodeKind kind)
+ {
+ this->kind = kind;
+ }
+ };
+
+ List *kind_stack;
+
static void on_start_element (gpointer user_data, const char *name,
const char **attrs);
static void on_end_element (gpointer user_data, const char *name);
static void on_text (gpointer user_data, const char *text, int len);
+
+ void AddEntry ();
+ PlaylistEntry *GetCurrentEntry ();
+
+ PlaylistContent *GetCurrentContent ();
+
+ void PushCurrentKind (PlaylistNodeKind kind);
+ void PopCurrentKind ();
+ PlaylistNodeKind GetCurrentKind ();
+ PlaylistNodeKind GetParentKind ();
+ void AssertParentKind (int kind);
+
public:
PlaylistParser (Playlist *list);
~PlaylistParser ();
- void Parse (const char *text, int len);
+ bool Parse (const char *text, int len);
};
G_END_DECLS
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches