00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00047 #include <xspf/XspfIndentFormatter.h>
00048 #include <xspf/XspfProps.h>
00049 #include <xspf/XspfReader.h>
00050 #include <xspf/XspfReaderCallback.h>
00051 #include <xspf/XspfTrack.h>
00052 #include <xspf/XspfWriter.h>
00053 #include <cstring>
00054
00055 extern "C" {
00056 #include "xspf_c.h"
00057 }
00058
00059 using namespace Xspf;
00060
00065 class XspfCReaderCallback : public XspfReaderCallback {
00066 private:
00071 xspf_list *list;
00076 xspf_track **newtrack;
00077
00081 void addTrack(XspfTrack *track);
00085 void setProps(XspfProps *props);
00086 public:
00090 XspfCReaderCallback(xspf_list *list);
00094 virtual ~XspfCReaderCallback();
00095 };
00096
00097 XspfCReaderCallback::XspfCReaderCallback(xspf_list *list)
00098 {
00099 this->list = list;
00100 newtrack = &list->tracks;
00101 }
00102
00103 XspfCReaderCallback::~XspfCReaderCallback()
00104 {
00105
00106 *newtrack = NULL;
00107 }
00108
00109 void
00110 XspfCReaderCallback::addTrack(XspfTrack *track)
00111 {
00112 xspf_mvalue **newmv;
00113 char *str;
00114
00115
00116 *newtrack = new xspf_track;
00117
00118 (*newtrack)->creator = track->stealCreator();
00119 (*newtrack)->title = track->stealTitle();
00120 (*newtrack)->album = track->stealAlbum();
00121 (*newtrack)->duration = track->getDuration();
00122 (*newtrack)->tracknum = track->getTrackNum();
00123 (*newtrack)->pdata = NULL;
00124
00125
00126 newmv = &(*newtrack)->locations;
00127 while ((str = track->stealFirstLocation()) != NULL) {
00128 *newmv = new xspf_mvalue;
00129 (*newmv)->value = str;
00130 (*newmv)->pdata = NULL;
00131
00132
00133 newmv = &(*newmv)->next;
00134 }
00135 *newmv = NULL;
00136
00137
00138 newmv = &(*newtrack)->identifiers;
00139 while ((str = track->stealFirstIdentifier()) != NULL) {
00140 *newmv = new xspf_mvalue;
00141 (*newmv)->value = str;
00142 (*newmv)->pdata = NULL;
00143
00144
00145 newmv = &(*newmv)->next;
00146 }
00147 *newmv = NULL;
00148
00149
00150 delete track;
00151 newtrack = &(*newtrack)->next;
00152 }
00153
00154 void
00155 XspfCReaderCallback::setProps(XspfProps *props)
00156 {
00157 list->license = props->stealLicense();
00158 list->location = props->stealLocation();
00159 list->identifier = props->stealIdentifier();
00160
00161 delete props;
00162 }
00163
00167 static void
00168 xspf_mvalue_free(struct xspf_mvalue *mv)
00169 {
00170 struct xspf_mvalue *nmv;
00171
00172 for (; mv != NULL; mv = nmv) {
00173
00174 nmv = mv->next;
00175 delete [] mv->value;
00176 delete mv;
00177 }
00178 }
00179
00180
00181
00182
00183
00184 extern "C" struct xspf_list *
00185 xspf_parse(char const *filename, char const *baseuri)
00186 {
00187 XspfReader read;
00188 xspf_list *ret;
00189
00190
00191 ret = new xspf_list;
00192
00193
00194 XspfCReaderCallback readcb(ret);
00195 if (read.parseFile(filename, &readcb, baseuri) == XSPF_READER_SUCCESS) {
00196
00197 return (ret);
00198 } else {
00199
00200 delete ret;
00201 return (NULL);
00202 }
00203 }
00204
00205 extern "C" struct xspf_list *
00206 xspf_parse_memory(char const *memory, int len_bytes, char const *baseuri)
00207 {
00208 XspfReader read;
00209 xspf_list *ret;
00210
00211
00212 ret = new xspf_list;
00213
00214
00215 XspfCReaderCallback readcb(ret);
00216 if (read.parseMemory(memory, len_bytes, &readcb, baseuri) == XSPF_READER_SUCCESS) {
00217
00218 return (ret);
00219 } else {
00220
00221 delete ret;
00222 return (NULL);
00223 }
00224 }
00225
00226 extern "C" struct xspf_list *
00227 xspf_new(void)
00228 {
00229 xspf_list *ret;
00230
00231 ret = new xspf_list;
00232 ret->license = NULL;
00233 ret->location = NULL;
00234 ret->identifier = NULL;
00235 ret->tracks = NULL;
00236 ret->pdata = NULL;
00237
00238 return (ret);
00239 }
00240
00241 extern "C" void
00242 xspf_free(struct xspf_list *list)
00243 {
00244 xspf_track *tr, *ntr;
00245
00246 delete [] list->license;
00247 delete [] list->location;
00248 delete [] list->identifier;
00249
00250 for (tr = list->tracks; tr != NULL; tr = ntr) {
00251
00252 ntr = tr->next;
00253
00254 delete [] tr->creator;
00255 delete [] tr->title;
00256 delete [] tr->album;
00257
00258 xspf_mvalue_free(tr->locations);
00259 xspf_mvalue_free(tr->identifiers);
00260
00261 delete tr;
00262 }
00263
00264 delete list;
00265 }
00266
00267 extern "C" void
00268 xspf_setvalue(char **str, char const *nstr)
00269 {
00270
00271 delete [] *str;
00272
00273 if (nstr == NULL) {
00274
00275 *str = NULL;
00276 } else {
00277
00278 size_t len;
00279 len = strlen(nstr) + 1;
00280 *str = new char[len];
00281 strcpy(*str, nstr);
00282 }
00283 }
00284
00285 extern "C" struct xspf_mvalue *
00286 xspf_new_mvalue_before(struct xspf_mvalue **mvalue)
00287 {
00288 xspf_mvalue *ret;
00289
00290 ret = new xspf_mvalue;
00291 ret->value = NULL;
00292 ret->pdata = NULL;
00293 ret->next = *mvalue;
00294 *mvalue = ret;
00295
00296 return (ret);
00297 }
00298
00299 extern "C" struct xspf_track *
00300 xspf_new_track_before(struct xspf_track **track)
00301 {
00302 xspf_track *ret;
00303
00304 ret = new xspf_track;
00305 ret->creator = NULL;
00306 ret->title = NULL;
00307 ret->album = NULL;
00308 ret->duration = -1;
00309 ret->tracknum = -1;
00310 ret->locations = NULL;
00311 ret->identifiers = NULL;
00312 ret->pdata = NULL;
00313 ret->next = *track;
00314 *track = ret;
00315
00316 return (ret);
00317 }
00318
00319 int
00320 xspf_write(struct xspf_list *list, char const *filename, char const *baseuri)
00321 {
00322 xspf_track *strack;
00323 xspf_mvalue *smvalue;
00324 XspfIndentFormatter formatter(-2);
00325 int error;
00326 XspfWriter * const writer = XspfWriter::makeWriter(formatter,
00327 baseuri, XspfWriter::NO_XML_BASE, &error);
00328 if (writer == NULL) {
00329 return error;
00330 }
00331
00332
00333 {
00334 XspfProps props;
00335 props.lendLicense(list->license);
00336 props.lendLocation(list->location);
00337 props.lendIdentifier(list->identifier);
00338 writer->setProps(props);
00339 }
00340
00341 XSPF_LIST_FOREACH_TRACK(list, strack) {
00342
00343 XspfTrack track;
00344 track.lendCreator(strack->creator);
00345 track.lendTitle(strack->title);
00346 track.lendAlbum(strack->album);
00347 track.setDuration(strack->duration);
00348 track.setTrackNum(strack->tracknum);
00349
00350
00351 XSPF_TRACK_FOREACH_LOCATION(strack,smvalue)
00352 track.lendAppendLocation(smvalue->value);
00353 XSPF_TRACK_FOREACH_IDENTIFIER(strack, smvalue)
00354 track.lendAppendIdentifier(smvalue->value);
00355
00356 writer->addTrack(track);
00357 }
00358
00359 int const res = writer->writeFile(filename);
00360 delete writer;
00361 return res;
00362 }