File indexing completed on 2024-04-21 04:53:59

0001 /*
0002     SPDX-FileCopyrightText: 2005 Koos Vriezen <koos.vriezen@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "config-kmplayer.h"
0008 
0009 #include "kmplayercommon_log.h"
0010 #include "kmplayer_asx.h"
0011 
0012 #include <QUrl>
0013 
0014 using namespace KMPlayer;
0015 
0016 static QString getAsxAttribute (Element * e, const QString & attr) {
0017     for (Attribute *a = e->attributes ().first (); a; a = a->nextSibling ())
0018         if (attr == a->name ().toString ().toLower ())
0019             return a->value ();
0020     return QString ();
0021 }
0022 
0023 Node *ASX::Asx::childFromTag (const QString & tag) {
0024     QByteArray ba = tag.toLatin1 ();
0025     const char *name = ba.constData ();
0026     if (!strcasecmp (name, "entry"))
0027         return new ASX::Entry (m_doc);
0028     else if (!strcasecmp (name, "entryref"))
0029         return new ASX::EntryRef (m_doc);
0030     else if (!strcasecmp (name, "title"))
0031         return new DarkNode (m_doc, name, id_node_title);
0032     else if (!strcasecmp (name, "base"))
0033         return new DarkNode (m_doc, name, id_node_base);
0034     else if (!strcasecmp (name, "param"))
0035         return new DarkNode (m_doc, name, id_node_param);
0036     return nullptr;
0037 }
0038 
0039 void *ASX::Asx::role (RoleType msg, void *content)
0040 {
0041     if (RolePlaylist == msg)
0042         return !title.isEmpty () ? (PlaylistRole *) this : nullptr;
0043     return Mrl::role (msg, content);
0044 }
0045 
0046 void ASX::Asx::closed () {
0047     for (Node *e = firstChild (); e; e = e->nextSibling ()) {
0048         if (e->id == id_node_title)
0049             title = e->innerText ().simplified ();
0050         else if (e->id == id_node_base)
0051             src = getAsxAttribute (static_cast <Element *> (e), "href");
0052     }
0053 }
0054 
0055 //-----------------------------------------------------------------------------
0056 
0057 Node *ASX::Entry::childFromTag (const QString & tag) {
0058     QByteArray ba = tag.toLatin1 ();
0059     const char *name = ba.constData ();
0060     if (!strcasecmp (name, "ref"))
0061         return new ASX::Ref (m_doc);
0062     else if (!strcasecmp (name, "title"))
0063         return new DarkNode (m_doc, name, id_node_title);
0064     else if (!strcasecmp (name, "base"))
0065         return new DarkNode (m_doc, name, id_node_base);
0066     else if (!strcasecmp (name, "param"))
0067         return new DarkNode (m_doc, name, id_node_param);
0068     else if (!strcasecmp (name, "starttime"))
0069         return new DarkNode (m_doc, name, id_node_starttime);
0070     else if (!strcasecmp (name, "duration"))
0071         return new DarkNode (m_doc, name, id_node_duration);
0072     return nullptr;
0073 }
0074 
0075 Node::PlayType ASX::Entry::playType () {
0076     return play_type_none;
0077 }
0078 
0079 void ASX::Entry::closed () {
0080     ref_child_count = 0;
0081     Node *ref = nullptr;
0082     for (Node *e = firstChild (); e; e = e->nextSibling ()) {
0083         switch (e->id) {
0084         case id_node_title:
0085             title = e->innerText (); // already normalized (hopefully)
0086             break;
0087         case id_node_base:
0088             src = getAsxAttribute (static_cast <Element *> (e), "href");
0089             break;
0090         case id_node_ref:
0091             ref = e;
0092             ref_child_count++;
0093         }
0094     }
0095     if (ref_child_count == 1 && !title.isEmpty ())
0096         static_cast <ASX::Ref *> (ref)->title = title;
0097 }
0098 
0099 void ASX::Entry::activate () {
0100     resolved = true;
0101     for (Node *e = firstChild (); e; e = e->nextSibling ())
0102         if (e->id == id_node_param) {
0103             Element * elm = static_cast <Element *> (e);
0104             if (getAsxAttribute(elm,"name").toLower() == QString("clipsummary")) {
0105                 QString inf = QUrl::fromPercentEncoding (
0106                                 getAsxAttribute (elm, "value").toUtf8 ());
0107                 document ()->message (MsgInfoString, &inf);
0108             }
0109         } else if (e->id == id_node_duration) {
0110             QString s = static_cast <Element *> (e)->getAttribute (
0111                     Ids::attr_value);
0112             int pos = parseTimeString( s );
0113             if (pos > 0)
0114                 duration_timer = document()->post (
0115                         this, new TimerPosting (pos * 10));
0116         }
0117     Mrl::activate ();
0118 }
0119 
0120 void ASX::Entry::message (MessageType msg, void *content) {
0121     if (msg == MsgEventTimer) {
0122         duration_timer = nullptr;
0123         deactivate ();
0124         return;
0125     }
0126     Mrl::message (msg, content);
0127 }
0128 
0129 void ASX::Entry::deactivate () {
0130     document ()->message (MsgInfoString, nullptr);
0131     if (duration_timer) {
0132         document()->cancelPosting (duration_timer);
0133         duration_timer = nullptr;
0134     }
0135     Mrl::deactivate ();
0136 }
0137 
0138 void *ASX::Entry::role (RoleType msg, void *content)
0139 {
0140     if (RolePlaylist == msg)
0141         return ref_child_count > 1 && !title.isEmpty ()
0142             ? (PlaylistRole *) this : nullptr;
0143     return Mrl::role (msg, content);
0144 }
0145 
0146 //-----------------------------------------------------------------------------
0147 
0148 void ASX::Ref::opened () {
0149     src = getAsxAttribute (this, "href");
0150     Mrl::opened ();
0151 }
0152 
0153 //-----------------------------------------------------------------------------
0154 
0155 void ASX::EntryRef::opened () {
0156     src = getAsxAttribute (this, "href");
0157     Mrl::opened ();
0158 }
0159