/* parse "create station" answer (it returns a new station structure) * @param piano handle * @param xml document * @return nothing yet */ PianoReturn_t PianoXmlParseCreateStation (PianoHandle_t *ph, char *xml) { ezxml_t xmlDoc, dataNode; PianoStation_t *tmpStation; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "struct", -1); if ((tmpStation = calloc (1, sizeof (*tmpStation))) == NULL) { ezxml_free (xmlDoc); return PIANO_RET_OUT_OF_MEMORY; } PianoXmlStructParser (dataNode, PianoXmlParseStationsCb, tmpStation); /* FIXME: copy & waste */ /* start new linked list or append */ if (ph->stations == NULL) { ph->stations = tmpStation; } else { PianoStation_t *curStation = ph->stations; while (curStation->next != NULL) { curStation = curStation->next; } curStation->next = tmpStation; } ezxml_free (xmlDoc); return PIANO_RET_OK; }
/* parse stations returned by pandora * @param piano handle * @param xml returned by pandora * @return _RET_OK or error */ PianoReturn_t PianoXmlParseStations (PianoHandle_t *ph, char *xml) { ezxml_t xmlDoc, dataNode; PianoReturn_t ret; char **quickMixIds = NULL, **curQuickMixId = NULL; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "array", 0, "data", -1); for (dataNode = ezxml_child (dataNode, "value"); dataNode; dataNode = dataNode->next) { PianoStation_t *tmpStation; if ((tmpStation = calloc (1, sizeof (*tmpStation))) == NULL) { ezxml_free (xmlDoc); return PIANO_RET_OUT_OF_MEMORY; } PianoXmlStructParser (ezxml_child (dataNode, "struct"), PianoXmlParseStationsCb, tmpStation); /* get stations selected for quickmix */ if (tmpStation->isQuickMix) { PianoXmlStructParser (ezxml_child (dataNode, "struct"), PianoXmlParseQuickMixStationsCb, &quickMixIds); } /* start new linked list or append */ if (ph->stations == NULL) { ph->stations = tmpStation; } else { PianoStation_t *curStation = ph->stations; while (curStation->next != NULL) { curStation = curStation->next; } curStation->next = tmpStation; } } /* set quickmix flags after all stations are read */ if (quickMixIds != NULL) { curQuickMixId = quickMixIds; while (*curQuickMixId != NULL) { PianoStation_t *curStation = PianoFindStationById (ph->stations, *curQuickMixId); if (curStation != NULL) { curStation->useQuickMix = 1; } free (*curQuickMixId); curQuickMixId++; } free (quickMixIds); } ezxml_free (xmlDoc); return PIANO_RET_OK; }
/* dummy function, only checks for errors * @param xml doc * @return _OK or error */ PianoReturn_t PianoXmlParseTranformStation (char *xml) { ezxml_t xmlDoc; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } ezxml_free (xmlDoc); return PIANO_RET_OK; }
/* check for exception only * @param xml string * @return _OK or error */ PianoReturn_t PianoXmlParseSimple (char *xml) { ezxml_t xmlDoc; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } ezxml_free (xmlDoc); return ret; }
/* parses "why did you play ...?" answer * @param xml * @param returns the answer * @return _OK or error */ PianoReturn_t PianoXmlParseNarrative (char *xml, char **retNarrative) { ezxml_t xmlDoc, dataNode; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } /* <methodResponse> <params> <param> <value> $textnode */ dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", -1); *retNarrative = strdup (ezxml_txt (dataNode)); ezxml_free (xmlDoc); return ret; }
/* parses userinfos sent by pandora as login response * @param piano handle * @param utf-8 string * @return _RET_OK or error */ PianoReturn_t PianoXmlParseUserinfo (PianoHandle_t *ph, char *xml) { ezxml_t xmlDoc, structNode; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } /* <methodResponse> <params> <param> <value> <struct> */ structNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "struct", -1); PianoXmlStructParser (structNode, PianoXmlParseUserinfoCb, &ph->user); ezxml_free (xmlDoc); return PIANO_RET_OK; }
/* parse getStation response */ PianoReturn_t PianoXmlParseGetStationInfo (char *xml, PianoStationInfo_t *stationInfo) { ezxml_t xmlDoc, dataNode; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "struct", -1); PianoXmlStructParser (dataNode, PianoXmlParseGetStationInfoCb, stationInfo); ezxml_free (xmlDoc); return PIANO_RET_OK; }
/* parse "add seed" answer, nearly the same as ParseCreateStation * @param piano handle * @param xml document * @param update this station */ PianoReturn_t PianoXmlParseAddSeed (char *xml, PianoStation_t *station) { ezxml_t xmlDoc, dataNode; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "struct", -1); PianoDestroyStation (station); PianoXmlStructParser (dataNode, PianoXmlParseStationsCb, station); ezxml_free (xmlDoc); return PIANO_RET_OK; }
/* parse search result; searchResult is nulled before use * @param xml document * @param returns search result * @return nothing yet */ PianoReturn_t PianoXmlParseSearch (char *xml, PianoSearchResult_t *searchResult) { ezxml_t xmlDoc, dataNode; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "struct", -1); /* we need a "clean" search result (with null pointers) */ memset (searchResult, 0, sizeof (*searchResult)); PianoXmlStructParser (dataNode, PianoXmlParseSearchCb, searchResult); ezxml_free (xmlDoc); return PIANO_RET_OK; }
/* FIXME: copy&waste (PianoXmlParseSearch) */ PianoReturn_t PianoXmlParseSeedSuggestions (char *xml, PianoSearchResult_t *searchResult) { ezxml_t xmlDoc, dataNode; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", -1); /* we need a "clean" search result (with null pointers) */ memset (searchResult, 0, sizeof (*searchResult)); /* reuse seach result parser; structure is nearly the same */ PianoXmlParseSearchCb ("artists", dataNode, searchResult); ezxml_free (xmlDoc); return PIANO_RET_OK; }
/* parse simple answers like this: <?xml version="1.0" encoding="UTF-8"?> * <methodResponse><params><param><value>1</value></param></params> * </methodResponse> * @param xml string * @return */ PianoReturn_t PianoXmlParseSimple (char *xml) { ezxml_t xmlDoc, dataNode; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", -1); if (strcmp (ezxml_txt (dataNode), "1") == 0) { ret = PIANO_RET_OK; } else { ret = PIANO_RET_ERR; } ezxml_free (xmlDoc); return ret; }
/* parses playlist; used when searching too * @param piano handle * @param xml document * @param return: playlist */ PianoReturn_t PianoXmlParsePlaylist (PianoHandle_t *ph, char *xml, PianoSong_t **retPlaylist) { ezxml_t xmlDoc, dataNode; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "array", 0, "data", -1); for (dataNode = ezxml_child (dataNode, "value"); dataNode; dataNode = dataNode->next) { PianoSong_t *tmpSong; if ((tmpSong = calloc (1, sizeof (*tmpSong))) == NULL) { ezxml_free (xmlDoc); return PIANO_RET_OUT_OF_MEMORY; } PianoXmlStructParser (ezxml_child (dataNode, "struct"), PianoXmlParsePlaylistCb, tmpSong); /* begin linked list or append */ if (*retPlaylist == NULL) { *retPlaylist = tmpSong; } else { PianoSong_t *curSong = *retPlaylist; while (curSong->next != NULL) { curSong = curSong->next; } curSong->next = tmpSong; } } ezxml_free (xmlDoc); return PIANO_RET_OK; }
/* parses playlist; used when searching too * @param piano handle * @param xml document * @param return: playlist */ PianoReturn_t PianoXmlParsePlaylist (PianoHandle_t *ph, char *xml, PianoSong_t **retPlaylist) { ezxml_t xmlDoc, dataNode; PianoReturn_t ret = PIANO_RET_OK; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "array", 0, "data", -1); for (dataNode = ezxml_child (dataNode, "value"); dataNode; dataNode = dataNode->next) { if ((ret = PianoXmlParsePlaylistStruct (dataNode, retPlaylist)) != PIANO_RET_OK) { break; } } ezxml_free (xmlDoc); return ret; }
PianoReturn_t PianoXmlParseGenreExplorer (PianoHandle_t *ph, char *xml) { ezxml_t xmlDoc, catNode; PianoReturn_t ret; if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) { return ret; } /* get all <member> nodes */ for (catNode = ezxml_child (xmlDoc, "category"); catNode; catNode = catNode->next) { PianoGenreCategory_t *tmpGenreCategory; ezxml_t genreNode; if ((tmpGenreCategory = calloc (1, sizeof (*tmpGenreCategory))) == NULL) { ezxml_free (xmlDoc); return PIANO_RET_OUT_OF_MEMORY; } tmpGenreCategory->name = strdup (ezxml_attr (catNode, "categoryName")); /* get genre subnodes */ for (genreNode = ezxml_child (catNode, "genre"); genreNode; genreNode = genreNode->next) { PianoGenre_t *tmpGenre; if ((tmpGenre = calloc (1, sizeof (*tmpGenre))) == NULL) { ezxml_free (xmlDoc); return PIANO_RET_OUT_OF_MEMORY; } /* get genre attributes */ tmpGenre->name = strdup (ezxml_attr (genreNode, "name")); tmpGenre->musicId = strdup (ezxml_attr (genreNode, "musicId")); /* append station */ if (tmpGenreCategory->genres == NULL) { tmpGenreCategory->genres = tmpGenre; } else { PianoGenre_t *curGenre = tmpGenreCategory->genres; while (curGenre->next != NULL) { curGenre = curGenre->next; } curGenre->next = tmpGenre; } } /* append category */ if (ph->genreStations == NULL) { ph->genreStations = tmpGenreCategory; } else { PianoGenreCategory_t *curCat = ph->genreStations; while (curCat->next != NULL) { curCat = curCat->next; } curCat->next = tmpGenreCategory; } } ezxml_free (xmlDoc); return PIANO_RET_OK; }