struct mpd_song * mpd_song_dup(const struct mpd_song *song) { struct mpd_song *ret; bool success; assert(song != NULL); ret = mpd_song_new(song->uri); if (ret == NULL) /* out of memory */ return NULL; for (unsigned i = 0; i < MPD_TAG_COUNT; ++i) { const struct mpd_tag_value *src_tag = &song->tags[i]; if (src_tag->value == NULL) continue; do { success = mpd_song_add_tag(ret, i, src_tag->value); if (!success) { mpd_song_free(ret); return NULL; } src_tag = src_tag->next; } while (src_tag != NULL); } ret->duration = song->duration; ret->start = song->start; ret->end = song->end; ret->last_modified = song->last_modified; ret->pos = song->pos; ret->id = song->id; #ifndef NDEBUG ret->finished = true; #endif return ret; }
bool mpd_song_feed(struct mpd_song *song, const struct mpd_pair *pair) { enum mpd_tag_type tag_type; assert(song != NULL); assert(!song->finished); assert(pair != NULL); assert(pair->name != NULL); assert(pair->value != NULL); if (strcmp(pair->name, "file") == 0) { #ifndef NDEBUG song->finished = true; #endif return false; } if (*pair->value == 0) return true; tag_type = mpd_tag_name_parse(pair->name); if (tag_type != MPD_TAG_UNKNOWN) { mpd_song_add_tag(song, tag_type, pair->value); return true; } if (strcmp(pair->name, "Time") == 0) mpd_song_set_duration(song, atoi(pair->value)); else if (strcmp(pair->name, "Range") == 0) mpd_song_parse_range(song, pair->value); else if (strcmp(pair->name, "Last-Modified") == 0) mpd_song_set_last_modified(song, iso8601_datetime_parse(pair->value)); else if (strcmp(pair->name, "Pos") == 0) mpd_song_set_pos(song, atoi(pair->value)); else if (strcmp(pair->name, "Id") == 0) mpd_song_set_id(song, atoi(pair->value)); return true; }
/** * Parses the mpd_song and correct the tags * * @return true if the tags have been corrected, false * otherwise (not an FM4 stream?) */ bool fm4_parse_stream(struct mpd_song *song) { const char *title = NULL; char *real_tag = NULL; char *real_artist = NULL; char *real_title = NULL; const char *pos_tag = NULL; const char *pos_artist = NULL; const char **dash_pointer = NULL; int n = 0; int numDash = 0; bool newChar = true; g_message("FM4: fm4_parse_stream\n"); if (song == NULL) return false; title = mpd_song_get_tag(song, MPD_TAG_TITLE, 0); if (title == NULL) return false; g_message("FM4: %s\n", title); /* parse TAG (program name)*/ pos_tag = strchr(title, ':'); if (pos_tag != NULL) { n = pos_tag - title; real_tag = strndup(title, n); } /* parse ARTIST */ ++pos_tag; /* ignore ':' */ if (isspace(*pos_tag)) ++pos_tag; /* ignore space */ pos_artist = strchr(pos_tag, '-'); if (pos_artist == NULL) { free(real_tag); return false; } /* check for '-' in artist tg */ for (const char *pos = pos_artist; pos != NULL; pos = strchr(pos + 1, '-')) { numDash++; } g_message("FM4: #Dashes: %d\n", numDash); if (numDash > 1) { int i = 0; bool allupper = true; dash_pointer = calloc(sizeof(const char *), numDash + 1); for (const char *pos = pos_artist; pos != NULL; pos = strchr(pos + 1, '-')) { dash_pointer[i] = pos; g_message("FM4: Dashes: %s\n", pos); i++; } /* Endpointer */ dash_pointer[i] = pos_artist + strlen(pos_artist); i = 1; for (const char *ptr = pos_artist + 1, *end = pos_artist + strlen(pos_artist); ptr < end; ptr++) { if (ptr >= dash_pointer[i]) { if (allupper) { /* all upper case chars, must be title */ break; } g_message("FM4: next dash: %s\n", dash_pointer[i]); pos_artist = dash_pointer[i]; i++; allupper = true; continue; } if (isalpha(*ptr) && islower(*ptr)) { allupper = false; } } free(dash_pointer); } g_message("FM4: pos_artist: %s\n", pos_artist); g_message("FM4: pos_tag: %s\n", pos_tag); n = pos_artist - pos_tag; real_artist = strndup(pos_tag, n); if (isspace(real_artist[n-1])) real_artist[n-1] = 0; /* ignore space */ /* parse TITLE */ ++pos_artist; /* ignore '-' */ if (isspace(*pos_artist)) ++pos_artist; /* ignore space */ real_title = strndup(pos_artist, strlen(pos_artist)); if (isspace(real_title[strlen(real_title)-1])) real_title[strlen(real_title)-1] = 0; /* ignore space */ /* Capitalize title string */ for (int i = 0, e = strlen(real_title); i < e; ++i) { char c = real_title[i]; if (isalpha(c)) { if (!islower(c)) { /* upper case char */ if (newChar) { /* first letter in the word */ newChar = false; } else { real_title[i] = tolower(c); } } } else if (isblank(c)) { /* new word */ newChar = true; } } g_message("FM4: title parsed: [%s] [%s] [%s]\n", real_tag, real_artist, real_title); mpd_song_clear_tag((struct mpd_song_hack *)song, MPD_TAG_TITLE); mpd_song_clear_tag((struct mpd_song_hack *)song, MPD_TAG_ARTIST); mpd_song_add_tag((struct mpd_song_hack *)song, MPD_TAG_TITLE, real_title); mpd_song_add_tag((struct mpd_song_hack *)song, MPD_TAG_ARTIST, real_artist); free(real_tag); free(real_artist); free(real_title); return true; }