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));