Logo Search packages:      
Sourcecode: zinf version File versions  Download package

pls.cpp

/*____________________________________________________________________________
      
      Zinf - Zinf Is Not FreeA*p (The Free MP3 Player)

      Portions Copyright (C) 1999 EMusic.com

      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
      the Free Software Foundation; either version 2 of the License, or
      (at your option) any later version.

      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.

      You should have received a copy of the GNU General Public License
      along with this program; if not, write to the Free Software
      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
      
      $Id: pls.cpp,v 1.8 2003/09/16 17:35:20 kgk Exp $
____________________________________________________________________________*/

#include <assert.h>
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>

#ifdef __QNX__
#include <strings.h>
#endif

using namespace std;

#include "config.h"
#include "errors.h"
#include "errno.h"
#include "utility.h"

#include "pls.h"
#include "debug.h"
#include "path_max.h"
#include "Http.h"

typedef struct FormatInfoStruct {
    const char* extension;
    const char* description;

} FormatInfoStruct; 

static FormatInfoStruct formats[] = {
    {"pls", "PLS Playlist Format"}
};

#define kNumFormats (sizeof(formats)/sizeof(FormatInfoStruct))

extern "C"
{
   PlaylistFormat *Initialize(FAContext* context)
   {
      return new PLS(context);
   }
}

PLS::PLS(FAContext* context):PlaylistFormat(context)
{
}

PLS::~PLS()
{

}

Error PLS::GetSupportedFormats(PlaylistFormatInfo* info, uint32_t index)
{
    Error result = kError_InvalidParam;

    assert(info);

    if(info)
    {
        result = kError_NoMoreFormats;

        if(index < kNumFormats)
        {
            info->SetExtension(formats[index].extension);
            info->SetDescription(formats[index].description);
            result = kError_NoErr;
        }
    }

    return result;
}







Error 
PLS::readPlaylist(const string& url, vector<string>& list)
{
    string path;
    string root;
    string title;
    string file;
    bool   removetmp= false;

    Error result = URLToFilePath(url, path);

    if (IsError(result)) {
        // It's a url.. get the local 
        Http download(m_context);
        char buffer[TMP_MAX];
        //cout << "download " << url << endl;
        tmpnam(buffer);
        path = buffer;
        result = download.DownloadToFile (url, path);
        //cout << "downloaded" << url <<"-> " << path << endl;
        removetmp = true;
    }

    if(IsError(result))
        return result;

    root =  path;
    string::size_type cp = root.rfind(DIR_MARKER);
    if(cp != string::npos)
        root.resize(cp+1);

    ifstream fp(path.c_str());
      
    if (!fp.is_open())
        return kError_FileNotFound;

    string   line;
    string   key;
    string   value;
    string::size_type pos;
    int32_t  len = -1;

    while(!fp.eof()) {
        getline(fp, line);

        pos = line.find('=');
        if (pos == string::npos)
            continue;
        key = line.substr(0,pos);
        value = line.substr(pos+1);

        if (key.substr(0,4) == "File"){
            if (file.size ()) {
                AddItem(list, file, title, len, root);
                title.resize(0);
                len = -1;
            }
            file = value;
        } else if (key.substr(0,5) == "Title"){
            title = value;
        } else if (key.substr(0,6) == "Length"){
            len = atoi(value.c_str());
        }
    }
    if (file.size())
        AddItem(list, file, title, len, root);
    fp.close();
    if (removetmp) unlink(path.c_str());

    return kError_NoErr;
}




Error
PLS::writePlaylist(const string& url,
                   std::vector<std::string>& items)
{

    Error result = kError_InvalidParam;
    return result;
}




Error PLS::ReadPlaylist( const char* url, 
                            std::vector<PlaylistItem*>* list,
                            PLMCallBackFunction function,
                            void* cookie )

{
    vector<string> items;

    Error r = readPlaylist (string(url), items);

    for (vector<string>::iterator i = items.begin();
         i != items.end(); i++) {
        PlaylistItem *item = new PlaylistItem(*i);
        list->push_back(item);
    }
    return r;


}

Error PLS::WritePlaylist(const char* url, PlaylistFormatInfo* format, 
                         vector<PlaylistItem*>* list,
                         PLMCallBackFunction function,
                         void* cookie)
{
    Error result = kError_InvalidParam;

    assert(url);
    assert(format);
    assert(list);

    if(url && format && list)
    {
        result = kError_FormatNotSupported;

        if(!strcasecmp("pls", format->GetExtension())) {
            FILE* fp = NULL;
            string path;

            URLToFilePath(url, path);

            result = kError_FileNoAccess;

            fp = fopen(path.c_str(), "wb");

            if(fp) {
                uint32_t index;
                uint32_t count;
                
                count = list->size();
                
                for(index = 0; index < count; index++) {
                    PlaylistItem* item = (*list)[index];


                    if(IsError(URLToFilePath(item->URL().c_str(), path)))
                        fprintf(fp, "%s%s", item->URL().c_str(), LINE_END_MARKER_STR);
                    else
                        fprintf(fp, "%s%s", path.c_str(), LINE_END_MARKER_STR);
                }

                fclose(fp);

                result = kError_NoErr;
            }
            else
            {
                int err = errno;

                switch(err)
                {
                    case EACCES:
                        result = kError_FileNoAccess;
                        break;

                    case EEXIST:
                        result = kError_FileNoAccess;
                        break;

                    case EINVAL:
                        result = kError_FileNoAccess;
                        break;

                    case ENOENT:
                        result = kError_FileNoAccess;
                        break;
                }
            }
        }
    }

    return result;
}


void PLS::AddItem(vector<string>& items,
                  string &entry, 
                  string&title, 
                  int32_t len, 
                  string&root)
{
    int index;
    string     path;

    // if this is not a URL then let's
    // enable people with different platforms 
    // to swap files by changing the path 
    // separator as necessary
    if( entry.substr(0,7)!= "http://" &&
        entry.substr(0,6)!= "rtp://" &&
        entry.substr(0,7)!= "file://")
    {
        for (index = entry.size() - 1; index >=0; index--)
        {
            if(entry[index] == '\\' && DIR_MARKER == '/')
                entry[index] = DIR_MARKER;
            else if(entry[index] == '/' && DIR_MARKER == '\\')
                entry[index] = DIR_MARKER;
        }
    }

    // get rid of nasty trailing whitespace
    for (index = entry.size() - 1; index >=0; index--)
    {
        if(!isspace(entry[index]))
            break;
    }
    entry.resize(index+1);

    // is there anything left?
    if(entry.size())
    {
        string urlitem;
        // is it a url already?
        if( entry.substr(0,7)== "http://" ||
            entry.substr(0,6)== "rtp://" ||
            entry.substr(0,7)== "file://")
        {
            //strcpy(path, entry);
            urlitem = entry;
        }
        else 
        {
            // is the path relative?
            if(entry.substr(0,2)== ".."
               || (entry.substr(1,2) !=":\\" 
                   && entry[0]!= DIR_MARKER))
            {
                path= root;
                path+= entry;
            }
            else
            {
                path= entry;
            }
            
            // make it a url so we can add it to the playlist

            FilePathToURL(path, urlitem);

        }
        items.push_back(urlitem);

#if 0
        // TODO should decide when to ride metadata to the datbase
        if (title || len > 0)
        {
            MetaData oData;
           
            if (title)
               oData.SetTitle(title);
            if (len > 0)
               oData.SetTime(len);

            item = new PlaylistItem(path, &oData);
        }
        else
            item = new PlaylistItem(path);

        list->push_back(item);
#endif
    }
}

#if 0
void PLS::AddItem(vector<PlaylistItem*>* list, string &entry, 
                  string &title, int32_t len, string &root)
{
    int32_t         index;
    PlaylistItem *item;
    string path;

    // if this is not a URL then let's
    // enable people with different platforms 
    // to swap files by changing the path 
    // separator as necessary
    if( strncmp(entry.c_str(), "http://", 7) &&
        strncmp(entry.c_str(), "rtp://", 6) &&
        strncmp(entry.c_str(), "file://", 7))
    {
      while((index = entry.find('\\'))>=0) {
          if(DIR_MARKER == '\\')
            break;
          else
            entry.replace(index,1,"/");
      }
      while((index = entry.find('/')) >= 0) {
          if(DIR_MARKER == '/')
            break;
          else
            entry.replace(index,1,"\\");
      }
    }

    // get rid of nasty trailing whitespace
    for (index = entry.length() - 1; index >=0; index--){
      if(entry.c_str()[index] == ' ')
          entry.erase(index,index);
      else
          break;
    }

    // is there anything left?
    if(entry.length())
    {
        // is it a url already?
        if (!strncmp(entry.c_str(), "http://", 7) ||
            !strncmp(entry.c_str(), "rtp://", 6) ||
            !strncmp(entry.c_str(), "file://", 7)) {
          path = entry;
        } else {
            // is the path relative?
          if(!entry.compare(0,2,"..") ||
            (entry.compare(1,2,":\\") &&
            entry.compare(0,1,DIR_MARKER_STR))){
              path = root;
            path += entry;
            } else
            path = entry;
            
            // make it a url so we can add it to the playlist
          string itemurl;

            if (IsntError(FilePathToURL(path.c_str(), itemurl)))
            path = itemurl;
        }

        if (title.length() || len > 0)
        {
            MetaData oData;
           
            if (title.length())
               oData.SetTitle(title.c_str());
            if (len > 0)
               oData.SetTime(len);

            item = new PlaylistItem(path.c_str(), &oData);
        }
        else
            item = new PlaylistItem(path.c_str());

        list->push_back(item);
    }
}
#endif

/* arch-tag: f39d6abc-ed70-4668-87d8-f09a4969ecc1
   (do not change this comment) */

Generated by  Doxygen 1.6.0   Back to index