Mercurial > audlegacy-plugins
comparison src/xspf/xspf.c @ 1278:d1c66f8ccf73
adapt xspf for file:// scheme.
author | Yoshiki Yazawa <yaz@cc.rim.or.jp> |
---|---|
date | Mon, 16 Jul 2007 23:47:42 +0900 |
parents | 173a67e7e4f8 |
children | 761e17b23e0c |
comparison
equal
deleted
inserted
replaced
1277:e7cd962732cb | 1278:d1c66f8ccf73 |
---|---|
56 return TRUE; | 56 return TRUE; |
57 else | 57 else |
58 return FALSE; | 58 return FALSE; |
59 } | 59 } |
60 | 60 |
61 #if 0 | |
61 static gboolean is_remote(gchar *uri) | 62 static gboolean is_remote(gchar *uri) |
62 { | 63 { |
63 if(strstr(uri, "file://")) | 64 if(strstr(uri, "file://")) |
64 return FALSE; | 65 return FALSE; |
65 | 66 |
66 if(strstr(uri, "://")) | 67 if(strstr(uri, "://")) |
67 return TRUE; | 68 return TRUE; |
68 else | 69 else |
69 return FALSE; | 70 return FALSE; |
70 } | 71 } |
72 #endif | |
71 | 73 |
72 // this function is taken from libxml2-2.6.27. | 74 // this function is taken from libxml2-2.6.27. |
73 static xmlChar *audPathToURI(const xmlChar *path) | 75 static xmlChar *audPathToURI(const xmlChar *path) |
74 { | 76 { |
75 xmlURIPtr uri; | 77 xmlURIPtr uri; |
108 // creator, album, title, duration, trackNum, annotation, image, | 110 // creator, album, title, duration, trackNum, annotation, image, |
109 for(nptr = track->children; nptr != NULL; nptr = nptr->next) { | 111 for(nptr = track->children; nptr != NULL; nptr = nptr->next) { |
110 if(nptr->type == XML_ELEMENT_NODE | 112 if(nptr->type == XML_ELEMENT_NODE |
111 && !xmlStrcmp(nptr->name, (xmlChar *)"location")) { | 113 && !xmlStrcmp(nptr->name, (xmlChar *)"location")) { |
112 gchar *str = (gchar *)xmlNodeGetContent(nptr); | 114 gchar *str = (gchar *)xmlNodeGetContent(nptr); |
113 gchar *tmp; | 115 gchar *tmp = NULL; |
114 | 116 |
115 #if 0 | 117 // tmp is escaped uri or a part of escaped uri. |
116 if(!is_remote(str)) { /* local file */ | 118 tmp = g_strdup_printf("%s%s", base ? base : "", str); |
117 tmp = (gchar *)xmlURIUnescapeString(str, -1, NULL); | 119 location = g_filename_from_uri(tmp, NULL, NULL); |
118 } | 120 if(!location) // http:// or something. |
119 else { /* streaming */ | 121 location = g_strdup(tmp); |
120 tmp = g_strdup(str); | 122 |
121 } | 123 xmlFree(str); str = NULL; |
122 #else | 124 g_free(tmp); tmp = NULL; |
123 tmp = g_strdup(str); // XXX | |
124 #endif | |
125 location = g_strdup_printf("%s%s", base ? base : "", tmp); | |
126 | |
127 xmlFree(str); | |
128 g_free(tmp); | |
129 } | 125 } |
130 else if(nptr->type == XML_ELEMENT_NODE | 126 else if(nptr->type == XML_ELEMENT_NODE |
131 && !xmlStrcmp(nptr->name, (xmlChar *)"title")) { | 127 && !xmlStrcmp(nptr->name, (xmlChar *)"title")) { |
132 tuple->track_name = (gchar *)xmlNodeGetContent(nptr); | 128 tuple->track_name = (gchar *)xmlNodeGetContent(nptr); |
133 } | 129 } |
197 } | 193 } |
198 | 194 |
199 } | 195 } |
200 | 196 |
201 if(location) { | 197 if(location) { |
198 gchar *uri = NULL; | |
202 tuple->file_name = g_path_get_basename(location); | 199 tuple->file_name = g_path_get_basename(location); |
203 tuple->file_path = g_path_get_dirname(location); | 200 tuple->file_path = g_path_get_dirname(location); |
201 #ifdef DEBUG | |
202 printf("xspf: tuple->file_name = %s\n", tuple->file_name); | |
203 printf("xspf: tuple->file_path = %s\n", tuple->file_path); | |
204 #endif | |
204 tuple->file_ext = g_strdup(strrchr(location, '.')); | 205 tuple->file_ext = g_strdup(strrchr(location, '.')); |
205 // add file to playlist | 206 // add file to playlist |
206 playlist_load_ins_file_tuple(playlist, location, filename, pos, tuple); | 207 uri = g_filename_to_uri(location, NULL, NULL); |
208 // uri would be NULL if location is already uri. --yaz | |
209 playlist_load_ins_file_tuple(playlist, uri ? uri: location, filename, pos, tuple); | |
210 g_free(uri); uri = NULL; | |
207 pos++; | 211 pos++; |
208 } | 212 } |
209 | 213 |
210 g_free(location); | 214 g_free(location); |
211 location = NULL; | 215 location = NULL; |
246 | 250 |
247 static void playlist_load_xspf(const gchar *filename, gint pos) | 251 static void playlist_load_xspf(const gchar *filename, gint pos) |
248 { | 252 { |
249 xmlDocPtr doc; | 253 xmlDocPtr doc; |
250 xmlNode *nptr, *nptr2; | 254 xmlNode *nptr, *nptr2; |
255 gchar *tmp = NULL; | |
251 | 256 |
252 g_return_if_fail(filename != NULL); | 257 g_return_if_fail(filename != NULL); |
253 | 258 #ifdef DEBUG |
259 printf("playlist_load_xspf: filename = %s\n", filename); | |
260 #endif | |
254 doc = xmlParseFile(filename); | 261 doc = xmlParseFile(filename); |
255 if(doc == NULL) | 262 if(doc == NULL) |
256 return; | 263 return; |
257 | 264 |
258 xmlFree(base); | 265 xmlFree(base); |
262 for(nptr = doc->children; nptr != NULL; nptr = nptr->next) { | 269 for(nptr = doc->children; nptr != NULL; nptr = nptr->next) { |
263 if(nptr->type == XML_ELEMENT_NODE | 270 if(nptr->type == XML_ELEMENT_NODE |
264 && !xmlStrcmp(nptr->name, (xmlChar *)"playlist")) { | 271 && !xmlStrcmp(nptr->name, (xmlChar *)"playlist")) { |
265 base = (gchar *)xmlNodeGetBase(doc, nptr); | 272 base = (gchar *)xmlNodeGetBase(doc, nptr); |
266 #ifdef DEBUG | 273 #ifdef DEBUG |
267 printf("load: base = %s\n", base); | 274 printf("playlist_load_xspf: base @1 = %s\n", base); |
268 #endif | 275 #endif |
269 { | 276 // if filename is specified as a base, ignore it. |
270 gchar *tmp = xmlURIUnescapeString(base, -1, NULL); | 277 tmp = xmlURIUnescapeString(base, -1, NULL); |
271 if(tmp) { | 278 if(tmp) { |
272 g_free(base); | 279 if(!strcmp(tmp, filename)) { |
273 base = tmp; | 280 xmlFree(base); |
281 base = NULL; | |
274 } | 282 } |
275 } | 283 g_free(tmp); |
276 | 284 tmp = NULL; |
277 if(!strcmp(base, filename)) { // filename is specified as a base URI. ignore. | 285 } |
278 xmlFree(base); | 286 #ifdef DEBUG |
279 base = NULL; | 287 printf("playlist_load_xspf: base @2 = %s\n", base); |
280 } | 288 #endif |
281 | |
282 for(nptr2 = nptr->children; nptr2 != NULL; nptr2 = nptr2->next) { | 289 for(nptr2 = nptr->children; nptr2 != NULL; nptr2 = nptr2->next) { |
283 | 290 |
284 if(nptr2->type == XML_ELEMENT_NODE | 291 if(nptr2->type == XML_ELEMENT_NODE |
285 && !xmlStrcmp(nptr2->name, (xmlChar *)"extension")) { | 292 && !xmlStrcmp(nptr2->name, (xmlChar *)"extension")) { |
286 //check if application is audacious | 293 //check if application is audacious |
308 xmlNodePtr rootnode, tmp, tracklist; | 315 xmlNodePtr rootnode, tmp, tracklist; |
309 GList *node; | 316 GList *node; |
310 gint baselen = 0; | 317 gint baselen = 0; |
311 Playlist *playlist = playlist_get_active(); | 318 Playlist *playlist = playlist_get_active(); |
312 | 319 |
320 #ifdef DEBUG | |
321 printf("playlist_save_xspf: filename = %s\n", filename); | |
322 #endif | |
313 xmlFree(base); | 323 xmlFree(base); |
314 base = NULL; | 324 base = NULL; |
315 | 325 |
316 doc = xmlNewDoc((xmlChar *)"1.0"); | 326 doc = xmlNewDoc((xmlChar *)"1.0"); |
317 | 327 |
321 rootnode = xmlNewNode(NULL, (xmlChar *)XSPF_ROOT_NODE_NAME); | 331 rootnode = xmlNewNode(NULL, (xmlChar *)XSPF_ROOT_NODE_NAME); |
322 xmlSetProp(rootnode, (xmlChar *)"version", (xmlChar *)"1"); | 332 xmlSetProp(rootnode, (xmlChar *)"version", (xmlChar *)"1"); |
323 xmlSetProp(rootnode, (xmlChar *)"xmlns", (xmlChar *)XSPF_XMLNS); | 333 xmlSetProp(rootnode, (xmlChar *)"xmlns", (xmlChar *)XSPF_XMLNS); |
324 | 334 |
325 PLAYLIST_LOCK(playlist->mutex); | 335 PLAYLIST_LOCK(playlist->mutex); |
336 | |
337 /* relative */ | |
326 if(playlist->attribute & PLAYLIST_USE_RELATIVE) { | 338 if(playlist->attribute & PLAYLIST_USE_RELATIVE) { |
327 /* prescan to determine base uri */ | 339 /* prescan to determine base uri */ |
328 for(node = playlist->entries; node != NULL; node = g_list_next(node)) { | 340 for(node = playlist->entries; node != NULL; node = g_list_next(node)) { |
329 gchar *ptr1, *ptr2; | 341 gchar *ptr1, *ptr2; |
330 PlaylistEntry *entry = PLAYLIST_ENTRY(node->data); | 342 PlaylistEntry *entry = PLAYLIST_ENTRY(node->data); |
331 gchar *tmp; | 343 gchar *tmp; |
332 gint tmplen = 0; | 344 gint tmplen = 0; |
333 | 345 |
334 if(!is_uri(entry->filename)) { | 346 if(!is_uri(entry->filename)) { //obsolete |
335 gchar *tmp2; | 347 gchar *tmp2; |
336 tmp2 = g_path_get_dirname(entry->filename); | 348 tmp2 = g_path_get_dirname(entry->filename); |
337 tmp = g_strdup_printf("%s/", tmp2); | 349 tmp = g_strdup_printf("%s/", tmp2); |
338 g_free(tmp2); | 350 g_free(tmp2); tmp2 = NULL; |
339 tmp2 = NULL; | 351 } |
340 } | 352 else { //uri |
341 else { | |
342 tmp = g_strdup(entry->filename); | 353 tmp = g_strdup(entry->filename); |
343 } | 354 } |
344 | 355 |
345 if(!base) { | 356 if(!base) { |
346 base = strdup(tmp); | 357 base = strdup(tmp); |
377 if(tmp) { | 388 if(tmp) { |
378 g_free(base); | 389 g_free(base); |
379 base = tmp; | 390 base = tmp; |
380 } | 391 } |
381 } | 392 } |
382 // xmlNodeSetBase(rootnode, base); // it blindly escapes characters. | |
383 | 393 |
384 if(!is_uri(base)) { | 394 if(!is_uri(base)) { |
395 #ifdef DEBUG | |
396 printf("base is not uri. something is wrong.\n"); | |
397 #endif | |
385 tmp = g_strdup_printf("file://%s", base); | 398 tmp = g_strdup_printf("file://%s", base); |
386 xmlSetProp(rootnode, (xmlChar *)"xml:base", (xmlChar *)tmp); | 399 xmlSetProp(rootnode, (xmlChar *)"xml:base", (xmlChar *)tmp); |
387 g_free(tmp); | 400 g_free(tmp); |
388 tmp = NULL; | 401 tmp = NULL; |
389 } | 402 } |
390 else | 403 else |
391 xmlSetProp(rootnode, (xmlChar *)"xml:base", (xmlChar *)base); | 404 xmlSetProp(rootnode, (xmlChar *)"xml:base", (xmlChar *)base); |
392 } | 405 } |
393 } /* USE_RELATIVE */ | 406 } /* USE_RELATIVE */ |
394 | 407 |
395 | 408 /* common */ |
396 xmlDocSetRootElement(doc, rootnode); | 409 xmlDocSetRootElement(doc, rootnode); |
397 | 410 |
398 tmp = xmlNewNode(NULL, (xmlChar *)"creator"); | 411 tmp = xmlNewNode(NULL, (xmlChar *)"creator"); |
399 xmlAddChild(tmp, xmlNewText((xmlChar *)PACKAGE "-" VERSION)); | 412 xmlAddChild(tmp, xmlNewText((xmlChar *)PACKAGE "-" VERSION)); |
400 xmlAddChild(rootnode, tmp); | 413 xmlAddChild(rootnode, tmp); |
413 xmlAddChild(rootnode, extension); | 426 xmlAddChild(rootnode, extension); |
414 } | 427 } |
415 | 428 |
416 tracklist = xmlNewNode(NULL, (xmlChar *)"trackList"); | 429 tracklist = xmlNewNode(NULL, (xmlChar *)"trackList"); |
417 xmlAddChild(rootnode, tracklist); | 430 xmlAddChild(rootnode, tracklist); |
418 | |
419 // PLAYLIST_LOCK(playlist->mutex); | |
420 | 431 |
421 for(node = playlist->entries; node != NULL; node = g_list_next(node)) { | 432 for(node = playlist->entries; node != NULL; node = g_list_next(node)) { |
422 PlaylistEntry *entry = PLAYLIST_ENTRY(node->data); | 433 PlaylistEntry *entry = PLAYLIST_ENTRY(node->data); |
423 xmlNodePtr track, location; | 434 xmlNodePtr track, location; |
424 gchar *filename = NULL; | 435 gchar *filename = NULL; |
425 | 436 |
426 track = xmlNewNode(NULL, (xmlChar *)"track"); | 437 track = xmlNewNode(NULL, (xmlChar *)"track"); |
427 location = xmlNewNode(NULL, (xmlChar *)"location"); | 438 location = xmlNewNode(NULL, (xmlChar *)"location"); |
428 | 439 |
429 if(is_uri(entry->filename)) { /* remote uri */ | 440 if(is_uri(entry->filename)) { /* uri */ |
430 gchar *tmp = NULL; | |
431 #ifdef DEBUG | 441 #ifdef DEBUG |
432 printf("filename is uri\n"); | 442 printf("filename is uri\n"); |
433 #endif | 443 #endif |
434 tmp = (gchar *)xmlURIEscape((xmlChar *)entry->filename); | 444 filename = g_strdup(entry->filename + baselen); // entry->filename is always uri now. |
435 filename = g_strdup(entry->filename + baselen); | 445 } |
436 g_free(tmp); | 446 else { /* local file (obsolete) */ |
437 tmp = NULL; | |
438 } | |
439 else { /* local file */ | |
440 gchar *tmp = | 447 gchar *tmp = |
441 (gchar *)audPathToURI((const xmlChar *)entry->filename + baselen); | 448 (gchar *)audPathToURI((const xmlChar *)entry->filename + baselen); |
442 if(base) { | 449 if(base) { /* relative */ |
443 filename = g_strdup_printf("%s", tmp); | 450 filename = g_strdup_printf("%s", tmp); |
444 } | 451 } |
445 else { | 452 else { |
446 #ifdef DEBUG | 453 #ifdef DEBUG |
447 printf("absolule, local\n"); | 454 printf("absolute and local (obsolete)\n"); |
448 #endif | 455 #endif |
449 filename = g_strdup_printf("file://%s", tmp); | 456 filename = g_filename_to_uri(tmp, NULL, NULL); |
450 } | 457 } |
451 g_free(tmp); | 458 g_free(tmp); tmp = NULL; |
452 tmp = NULL; | 459 } /* obsolete */ |
453 } | |
454 | 460 |
455 if(!g_utf8_validate(filename, -1, NULL)) | 461 if(!g_utf8_validate(filename, -1, NULL)) |
456 continue; | 462 continue; |
457 | 463 |
458 xmlAddChild(location, xmlNewText((xmlChar *)filename)); | 464 xmlAddChild(location, xmlNewText((xmlChar *)filename)); |