source: titan/minidlna-1.0.22/tagutils/tagutils-plist.c @ 13567

Last change on this file since 13567 was 13567, checked in by obi, 12 years ago

[titan] add minidlna-1.0.22 first step

File size: 4.5 KB
Line 
1//=========================================================================
2// FILENAME     : playlist.c
3// DESCRIPTION  : Playlist
4//=========================================================================
5// Copyright (c) 2008- NETGEAR, Inc. All Rights Reserved.
6//=========================================================================
7
8/*
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.
13 *
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.
18 *
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/>.
21 */
22
23#include <stdio.h>
24#include <string.h>
25#include <ctype.h>
26
27#include "misc.h"
28#include "tagutils.h"
29#include "textutils.h"
30#include "log.h"
31
32
33#define MAX_BUF 4096
34
35static FILE *fp = 0;
36static int _utf8bom = 0;
37static int _trackno;
38
39static int (*_next_track)(struct song_metadata*, struct stat*, char*, char*);
40static int _m3u_next_track(struct song_metadata*, struct stat*, char*, char*);
41static int _pls_next_track(struct song_metadata*, struct stat*, char*, char*);
42
43int
44start_plist(const char *path, struct song_metadata *psong, struct stat *stat, char *lang, char *type)
45{
46        char *fname, *suffix;
47
48        _next_track = 0;
49        _utf8bom = 0;
50        _trackno = 0;
51
52        if(strcasecmp(type, "m3u") == 0)
53                _next_track = _m3u_next_track;
54        else if(strcasecmp(type, "pls") == 0)
55                _next_track = _pls_next_track;
56
57        if(!_next_track)
58        {
59                DPRINTF(E_ERROR, L_SCANNER, "Unsupported playlist type <%s> (%s)\n", type, path);
60                return -1;
61        }
62
63        if(!(fp = fopen(path, "rb")))
64        {
65                DPRINTF(E_ERROR, L_SCANNER, "Cannot open %s\n", path);
66                return -1;
67        }
68
69        if(!psong)
70                return 0;
71
72        memset((void*)psong, 0, sizeof(struct song_metadata));
73        psong->is_plist = 1;
74        psong->path = strdup(path);
75        psong->type = type;
76
77        fname = strrchr(psong->path, '/');
78        psong->basename = fname ? fname + 1 : psong->path;
79
80        psong->title = strdup(psong->basename);
81        suffix = strrchr(psong->title, '.');
82        if(suffix) *suffix = '\0';
83
84        if(stat)
85        {
86                if(!psong->time_modified)
87                        psong->time_modified = stat->st_mtime;
88                psong->file_size = stat->st_size;
89        }
90
91        return 0;
92}
93
94int
95_m3u_next_track(struct song_metadata *psong, struct stat *stat, char *lang, char *type)
96{
97        char buf[MAX_BUF], *p;
98        int len;
99
100        //
101        memset((void*)psong, 0, sizeof(struct song_metadata));
102
103        // read first line, check BOM
104        p = fgets(buf, MAX_BUF, fp);
105        if(!p)
106        {
107                fclose(fp);
108                return 1;
109        }
110
111        if(!_utf8bom && p[0] == '\xef' && p[1] == '\xbb' && p[2] == '\xbf')
112        {
113                _utf8bom = 1;
114                p += 3;
115        }
116
117        while(p)
118        {
119                while(isspace(*p)) p++;
120
121                if(!isprint(*p))
122                {
123                        DPRINTF(E_ERROR, L_SCANNER, "Playlist looks bad (unprintable characters)\n");
124                        fclose(fp);
125                        return 2;
126                }
127
128                if(*p && *p != '#')
129                {
130                        // check dos format
131                        len = strlen((char*)p);
132
133                        while(p[len - 1] == '\r' || p[len - 1] == '\n')
134                        {
135                                p[--len] = '\0';
136                        }
137                        psong->path = strdup(p);
138                        psong->track = ++_trackno;
139                        return 0;
140                }
141                p = fgets(buf, MAX_BUF, fp);
142                continue;
143        }
144
145        fclose(fp);
146        return 1;
147}
148
149int
150_pls_next_track(struct song_metadata *psong, struct stat *stat, char *lang, char *type)
151{
152        char buf[MAX_BUF], *p;
153        int len;
154
155        memset((void*)psong, 0, sizeof(struct song_metadata));
156
157        // read first line
158        p = fgets(buf, MAX_BUF, fp);
159
160        while(p)
161        {
162                while(isspace(*p)) p++;
163
164                if(!isprint(*p))
165                {
166                        DPRINTF(E_ERROR, L_SCANNER, "Playlist looks bad (unprintable characters)\n");
167                        fclose(fp);
168                        return 2;
169                }
170
171                if(*p && *p != '#')
172                {
173                        // verify that it's a valid pls playlist
174                        if(!_trackno)
175                        {
176                                if(strncmp(p, "[playlist]", 10))
177                                        break;
178                                _trackno++;
179                                goto next_line;
180                        }
181
182                        if(strncmp(p, "File", 4))
183                                goto next_line;
184
185                        psong->track = strtol(p+4, &p, 10);
186                        if(!psong->track || !p)
187                                goto next_line;
188                        _trackno = psong->track;
189                        // check dos format
190                        len = strlen(++p);
191
192                        while(p[len - 1] == '\r' || p[len - 1] == '\n')
193                        {
194                                p[--len] = '\0';
195                        }
196                        psong->path = strdup(p);
197                        return 0;
198                }
199next_line:
200                p = fgets(buf, MAX_BUF, fp);
201        }
202
203        fclose(fp);
204        return 1;
205}
206
207int
208next_plist_track(struct song_metadata *psong, struct stat *stat, char *lang, char *type)
209{
210        if(_next_track)
211                return _next_track(psong, stat, lang, type);
212        return -1;
213}
Note: See TracBrowser for help on using the repository browser.