~ubuntu-branches/ubuntu/jaunty/moon/jaunty

« back to all changes in this revision

Viewing changes to src/playlist.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2009-03-06 10:09:49 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090306100949-pgxjxjqltaxi12rz
Tags: 1.0.1-0ubuntu1
New upstream release (LP: #338665)

Show diffs side-by-side

added added

removed removed

Lines of Context:
834
834
static bool
835
835
str_match (const char *candidate, const char *tag)
836
836
{
837
 
        return g_strcasecmp (candidate, tag) == 0;
 
837
        return g_ascii_strcasecmp (candidate, tag) == 0;
838
838
}
839
839
 
840
840
void
976
976
        return true;
977
977
}
978
978
 
 
979
static bool
 
980
is_valid_protocol (const char *proto)
 
981
{
 
982
        return proto != NULL && (
 
983
                g_ascii_strncasecmp (proto, "http", 4) == 0 || 
 
984
                g_ascii_strncasecmp (proto, "https", 5) == 0 ||
 
985
                g_ascii_strncasecmp (proto, "mms", 3) == 0 ||
 
986
                g_ascii_strncasecmp (proto, "rtsp", 4) == 0 ||
 
987
                g_ascii_strncasecmp (proto, "rstpt", 5) == 0
 
988
        );
 
989
}
 
990
 
979
991
void
980
992
PlaylistParser::OnStartElement (const char *name, const char **attrs)
981
993
{
1039
1051
                                        uri = new Uri ();
1040
1052
                                        if (!uri->Parse (attrs [i+1], true)) {
1041
1053
                                                failed = true;
1042
 
                                        } else if (uri->protocol == NULL) {
1043
 
                                                failed = true;
1044
 
                                        } else if (g_strcasecmp (uri->protocol, "http") && 
1045
 
                                                   g_strcasecmp (uri->protocol, "https") && 
1046
 
                                                   g_strcasecmp (uri->protocol, "mms") &&
1047
 
                                                   g_strcasecmp (uri->protocol, "rtsp") && 
1048
 
                                                   g_strcasecmp (uri->protocol, "rstpt")) {
 
1054
                                        } else if (!is_valid_protocol (uri->protocol)) {
1049
1055
                                                failed = true;
1050
1056
                                        }
1051
1057
 
1208
1214
        case PlaylistNode::Repeat:
1209
1215
        case PlaylistNode::Param:
1210
1216
        case PlaylistNode::Event:
1211
 
                ParsingError (new ErrorEventArgs (MediaError, 3006, "Unsupported ASX element"));
 
1217
                if (element->GetSurface ()->GetRelaxedMediaMode ()) {
 
1218
                        LOG_PLAYLIST ("PlaylistParser::OnStartElement ('%s', %p): "
 
1219
                                "Unsupported kind: %d, ignoring in relaxed mode\n", name, attrs, kind);
 
1220
                } else {
 
1221
                        ParsingError (new ErrorEventArgs (MediaError, 3006, "Unsupported ASX element"));
 
1222
                }
1212
1223
                break;
1213
1224
        case PlaylistNode::Root:
1214
1225
        case PlaylistNode::Unknown:
1215
1226
        default:
1216
1227
                LOG_PLAYLIST ("PlaylistParser::OnStartElement ('%s', %p): Unknown kind: %d\n", name, attrs, kind);
1217
 
                ParsingError (new ErrorEventArgs (MediaError, 3004, "Invalid ASX element"));
 
1228
                if (!element->GetSurface ()->GetRelaxedMediaMode ()) {
 
1229
                        ParsingError (new ErrorEventArgs (MediaError, 3004, "Invalid ASX element"));
 
1230
                }
1218
1231
                break;
1219
1232
        }
1220
1233
}
1305
1318
                }
1306
1319
                break;
1307
1320
        default:
 
1321
                if (kind == PlaylistNode::Param && element->GetSurface ()->GetRelaxedMediaMode ()) {
 
1322
                        if (!AssertParentKind (PlaylistNode::Asx))
 
1323
                                break;
 
1324
                        break;          
 
1325
                }
 
1326
 
1308
1327
                LOG_PLAYLIST ("PlaylistParser::OnEndElement ('%s'): Unknown kind %d.\n", name, kind);
1309
1328
                ParsingError (new ErrorEventArgs (MediaError, 3008, "ASX parse error"));
1310
1329
                break;
1359
1378
        if (!source->Peek (buffer, asx_header_length))
1360
1379
                return false;
1361
1380
                
1362
 
        return strncmp (asx_header, buffer, asx_header_length) == 0;
 
1381
        return g_ascii_strncasecmp (asx_header, buffer, asx_header_length) == 0;
1363
1382
}
1364
1383
 
1365
1384
bool
1372
1391
        if (!source->Peek (buffer, asx2_header_length))
1373
1392
                return false;
1374
1393
                
1375
 
        return strncmp (asx2_header, buffer, asx2_header_length) == 0;
 
1394
        return g_ascii_strncasecmp (asx2_header, buffer, asx2_header_length) == 0;
 
1395
}
 
1396
 
 
1397
bool
 
1398
PlaylistParser::IsPossibleUrlList (IMediaSource *source)
 
1399
{
 
1400
        // This is a relaxed mode "format" that just covers a bunch of random
 
1401
        // awful corner cases found on the web for Moonshine/WMP compat, like
 
1402
        // 'ASF http://...' (seriously)
 
1403
 
 
1404
        char buffer[20];
 
1405
        char *p;
 
1406
 
 
1407
        memset (buffer, 0, sizeof (buffer));
 
1408
 
 
1409
        if (!source->Peek (buffer, sizeof (buffer) - 1))
 
1410
                return false;
 
1411
        
 
1412
        // Ignore "IGNORE " from "IGNORE <proto>"
 
1413
        p = g_strstr_len (buffer, sizeof (buffer) - 8, " ");
 
1414
        p = p == NULL ? buffer : p + 1;
 
1415
 
 
1416
        return is_valid_protocol (p);
1376
1417
}
1377
1418
 
1378
1419
bool
1502
1543
        return true;
1503
1544
}
1504
1545
 
 
1546
bool
 
1547
PlaylistParser::IsValidPlaylist (IMediaSource *source)
 
1548
{
 
1549
        return PlaylistParser::IsASX3 (source) || 
 
1550
                PlaylistParser::IsASX2 (source) ||
 
1551
                (source->GetMedia ()->GetSurface ()->GetRelaxedMediaMode () && 
 
1552
                        PlaylistParser::IsPossibleUrlList (source));
 
1553
}
 
1554
 
1505
1555
MediaResult
1506
1556
PlaylistParser::Parse ()
1507
1557
{
1520
1570
                if (size != -1 && last_available_pos != -1 && size != last_available_pos)
1521
1571
                        return MEDIA_NOT_ENOUGH_DATA; 
1522
1572
 
1523
 
                if (!this->IsASX3 (source) && this->IsASX2 (source)) {
 
1573
                if (!PlaylistParser::IsASX3 (source) && PlaylistParser::IsASX2 (source)) {
1524
1574
                        /* Parse as a asx2 mms file */
1525
1575
                        result = this->ParseASX2 ();
 
1576
                } else if (element->GetSurface ()->GetRelaxedMediaMode () && PlaylistParser::IsPossibleUrlList (source)) {
 
1577
                        result = this->ParsePossibleUrlList ();
1526
1578
                } else {
1527
1579
                        result = this->ParseASX3 ();
1528
1580
                }
1573
1625
        return playlist != NULL;
1574
1626
}
1575
1627
 
 
1628
bool
 
1629
PlaylistParser::ParsePossibleUrlList ()
 
1630
{
 
1631
        const int BUFFER_SIZE = 1024;
 
1632
        int bytes_read, i;
 
1633
        char buffer[BUFFER_SIZE];
 
1634
        char **lines;
 
1635
        
 
1636
        playlist_version = 3;
 
1637
 
 
1638
        bytes_read = source->ReadSome (buffer, BUFFER_SIZE);
 
1639
        if (bytes_read <= 0) {
 
1640
                LOG_PLAYLIST_WARN ("Could not read possible playlist document for parsing.\n");
 
1641
                return false;
 
1642
        }
 
1643
 
 
1644
        buffer[bytes_read] = 0;
 
1645
        lines = g_strsplit_set (buffer, "\r\n", -1);
 
1646
 
 
1647
        current_entry = NULL;
 
1648
        playlist = NULL;
 
1649
 
 
1650
        for (i = 0; lines[i]; i++) {
 
1651
                char *p = g_strstr_len (lines[i], 12, " ");
 
1652
                p = p == NULL ? lines[i] : p + 1;
 
1653
                if (is_valid_protocol (p)) {
 
1654
                        Uri *uri = new Uri ();
 
1655
                        if (uri->Parse (p)) {
 
1656
                                if (playlist == NULL) {
 
1657
                                        playlist = new Playlist (element, source);
 
1658
                                }
 
1659
 
 
1660
                                PlaylistEntry *entry = new PlaylistEntry (element, playlist);
 
1661
                                entry->SetSourceName (uri);
 
1662
                                playlist->AddEntry (entry);
 
1663
                                
 
1664
                                if (current_entry == NULL) {
 
1665
                                        current_entry = entry;
 
1666
                                }
 
1667
                        } else {
 
1668
                                LOG_PLAYLIST_WARN ("Could not parse URI from possible playlist: %s.\n", p);
 
1669
                                delete uri;
 
1670
                        }
 
1671
                }
 
1672
        }
 
1673
 
 
1674
        g_strfreev (lines);
 
1675
 
 
1676
        if (playlist == NULL || current_entry == NULL) {
 
1677
                LOG_PLAYLIST_WARN ("No valid URIs in possible playlist\n");
 
1678
                return false;
 
1679
        }
 
1680
 
 
1681
        return true;
 
1682
}
 
1683
 
1576
1684
PlaylistEntry *
1577
1685
PlaylistParser::GetCurrentContent ()
1578
1686
{