1 //=========================================================================
2 // FILENAME : playlist.c
3 // DESCRIPTION : Playlist
4 //=========================================================================
5 // Copyright (c) 2008- NETGEAR, Inc. All Rights Reserved.
6 //=========================================================================
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 #include "textutils.h"
36 static int _utf8bom
= 0;
39 static int (*_next_track
)(struct song_metadata
*, struct stat
*, char*, char*);
40 static int _m3u_pls_next_track(struct song_metadata
*, struct stat
*, char*, char*);
43 start_plist(const char *path
, struct song_metadata
*psong
, struct stat
*stat
, char *lang
, char *type
)
51 if(strcasecmp(type
, "m3u") == 0)
52 _next_track
= _m3u_pls_next_track
;
53 else if(strcasecmp(type
, "pls") == 0)
54 _next_track
= _m3u_pls_next_track
;
58 DPRINTF(E_ERROR
, L_SCANNER
, "Unsupported playlist type <%s> (%s)\n", type
, path
);
62 if(!(fp
= fopen(path
, "rb")))
64 DPRINTF(E_ERROR
, L_SCANNER
, "Cannot open %s\n", path
);
71 memset((void*)psong
, 0, sizeof(struct song_metadata
));
73 psong
->path
= strdup(path
);
76 fname
= strrchr(psong
->path
, '/');
77 psong
->basename
= fname
? fname
+ 1 : psong
->path
;
79 psong
->title
= strdup(psong
->basename
);
80 suffix
= strrchr(psong
->title
, '.');
81 if(suffix
) *suffix
= '\0';
85 if(!psong
->time_modified
)
86 psong
->time_modified
= stat
->st_mtime
;
87 psong
->file_size
= stat
->st_size
;
94 _m3u_pls_next_track(struct song_metadata
*psong
, struct stat
*stat
, char *lang
, char *type
)
96 char buf
[MAX_BUF
], *p
;
99 memset((void*)psong
, 0, sizeof(struct song_metadata
));
102 p
= fgets(buf
, MAX_BUF
, fp
);
109 if(strcasecmp(type
, "m3u") == 0)
112 if(!_utf8bom
&& p
[0] == '\xef' && p
[1] == '\xbb' && p
[2] == '\xbf')
121 while(isspace(*p
)) p
++;
123 if(!(*p
) || *p
== '#')
128 DPRINTF(E_ERROR
, L_SCANNER
, "Playlist looks bad (unprintable characters)\n");
133 if(strcasecmp(type
, "pls") == 0)
135 // verify that it's a valid pls playlist
138 if(strncmp(p
, "[playlist]", 10))
144 if(strncmp(p
, "File", 4) != 0)
147 psong
->track
= strtol(p
+4, &p
, 10);
148 if(!psong
->track
|| !p
++)
150 _trackno
= psong
->track
;
152 else if(strcasecmp(type
, "m3u") == 0)
153 psong
->track
= ++_trackno
;
156 while(p
[len
-1] == '\r' || p
[len
-1] == '\n')
158 psong
->path
= strdup(p
);
161 p
= fgets(buf
, MAX_BUF
, fp
);
169 next_plist_track(struct song_metadata
*psong
, struct stat
*stat
, char *lang
, char *type
)
172 return _next_track(psong
, stat
, lang
, type
);