Пример #1
0
Error PMP300::WritePlaylist(DeviceInfo* device, 
                            vector<PlaylistItem*>* list,
                            PLMCallBackFunction function,
                            void* cookie)
{
    Error result = kError_InvalidParam;

    assert(device);
    assert(list);

    if(device && list)
    {
        result = kError_DeviceNotFound;

        if(!strcasecmp(device->GetDevice(), devices[0].device))
        {
            CRio rioInternal, rioExternal;
            bool rioPresent = false;

            rioPresent = FindRio(rioInternal, device, function, cookie);

            if(rioPresent)
            {
                FindRio(rioExternal, device, function, cookie);

                rioExternal.UseExternalFlash(true);

                if(function)
                {
                    PLMEvent event;
    
                    event.type = kPLMEvent_Status;
                    event.eventString += "A ";
                    event.eventString = device->GetDevice();
                    event.eventString += " has been found. Scanning internal memory...";

                    function(&event, cookie);
                }     

                vector<PlaylistItem*> origInternal;
                vector<PlaylistItem*> origExternal;
                vector<PlaylistItem*> newInternal;
                vector<PlaylistItem*> newExternal;
                uint32 externalTotal = 0, internalTotal = 0, usedMem; 
                uint32 count, index;
                char* path = new char[_MAX_PATH];
                char* tempPath = new char[_MAX_PATH];
                uint32 length = _MAX_PATH;

                // get a temp path
                m_context->prefs->GetPrefString(kInstallDirPref, tempPath, &length);
                strcat(tempPath, tmpnam(NULL));

#ifdef WIN32
                mkdir(tempPath);
#else
                mkdir(tempPath, S_IRWXU);
#endif

                // first get current state of device
                // we break our lists into internal and 
                // external lists for ease of organizing
                result = privateReadPlaylist(rioInternal, 
                                             false,  
                                             &internalTotal,
                                             &usedMem,
                                             &origInternal, 
                                             function, 
                                             cookie); 
                
                if(IsntError(result))
                {
                    if(function)
                    {
                        PLMEvent event;

                        event.type = kPLMEvent_Status;
                        event.eventString = "Scanning external memory...";

                        function(&event, cookie);
                    }

                    privateReadPlaylist(rioExternal, 
                                        true,  
                                        &externalTotal,
                                        &usedMem,
                                        &origExternal, 
                                        function, 
                                        cookie);    
                }

                count = list->size();
                bool useExternal = false;

                for(index = 0; index < count; index++)
                {
                    PlaylistItem* item = (*list)[index];
                    
                    if(item)
                    {
                        MetaData metadata = item->GetMetaData();

                        int32 size = metadata.Size();

                        if(!size)
                        {
                            struct stat st;

                            length = _MAX_PATH;

                            URLToFilePath(item->URL().c_str(), path, &length);

                            if(!stat(path, &st))
                                size = st.st_size;
                            else
                            {
                                result = kError_FileNoAccess;
                                break;
                            }
                        }
                        
                        // figure out where to put it...
                        uint32* memorySize;
                        vector<PlaylistItem*>* addList;

                        if(!useExternal)
                        {
                            memorySize = &internalTotal;
                            addList = &newInternal;

                            if(*memorySize < (uint32)size)
                                useExternal = true;
                            else
                                *memorySize -= size;
                        }
                        
                        if(useExternal)
                        {
                            memorySize = &externalTotal;
                            addList = &newExternal;

                            if(*memorySize < (uint32)size)
                                break;
                            else
                                *memorySize -= size;
                        }
                        
                        addList->push_back(item);
                    }
                }

                // if all is well we delete old files
                // and temporarily download files
                // that are being moved from internal
                // to external and vice versa...
                if(IsntError(result))
                {
                    if(function)
                    {
                        PLMEvent event;

                        event.type = kPLMEvent_Status;
                        event.eventString = "Deleting files...";

                        function(&event, cookie);
                    }

                    count = origInternal.size();

                    for(index = 0; index < count; index++)
                    {
                        PlaylistItem* item = origInternal[index];

                        if(find_if(newInternal.begin(), 
                                   newInternal.end(), 
                                   PlaylistItemCompare(item)) == newInternal.end())
                        {
                            // need to delete it
                            vector<PlaylistItem*>::iterator position;

                            if((position = find_if(newExternal.begin(), 
                                                   newExternal.end(), 
                                                   PlaylistItemCompare(item))) != newExternal.end())
                            {
                                // need to download it to temp file first
                                // and then upload it to other card
                                // in the next stage...

                                string itemPath = item->URL();
                                string downloadPath = tempPath;
                                downloadPath += DIR_MARKER_STR;

                                downloadPath.insert(downloadPath.size(), 
                                                    itemPath, 
                                                    itemPath.rfind('/') + 1, 
                                                    itemPath.size());

                                RioProgressStruct ps;

                                memset(&ps, 0x00, sizeof(ps));

                                ps.function = function;
                                ps.cookie = cookie;
                                ps.item = item;

                                if(!rioInternal.RxFile(downloadPath.c_str(), rioProgress, &ps))
                                {
                                    if(function)
                                    {
                                        PLMEvent event;
    
                                        event.type = kPLMEvent_Error;
                                        event.data.errorData.errorCode = rioInternal.GetErrorID();
                                        event.eventString = "Download failed, ";
                                        event.eventString += rioInternal.GetErrorStr();

                                        function(&event, cookie);
                                    }

                                    if(rioInternal.GetErrorID() == CRIO_ERROR_INTERRUPTED)
                                        result = kError_UserCancel;
                                    else
                                        result = kError_UnknownErr;
                                    break;
                                }

                                length = _MAX_PATH;
                                FilePathToURL(downloadPath.c_str(), path, &length);

                                (*position)->SetURL(path);
                            }

                            string::size_type pos = item->URL().rfind("/") + 1;
                            const char* cp = item->URL().c_str();

                            if(!rioInternal.RemoveFile(cp + pos))
                            {
                                if(function)
                                {
                                    PLMEvent event;
            
                                    event.type = kPLMEvent_Error;
                                    event.data.errorData.errorCode = rioInternal.GetErrorID();
                                    event.eventString = "Delete failed, ";
                                    event.eventString += rioInternal.GetErrorStr();

                                    function(&event, cookie);
                                }

                                result = kError_UnknownErr;
                                break;
                            }

                            delete item;
                            origInternal[index] = NULL;
                        }
                    }

                    if(IsntError(result))
                    {
                        count = origExternal.size();

                        for(index = 0; index < count; index++)
                        {
                            PlaylistItem* item = origExternal[index];

                            if(find_if(newExternal.begin(), 
                                       newExternal.end(), 
                                       PlaylistItemCompare(item)) == newExternal.end())
                            {
                                // need to delete it

                                vector<PlaylistItem*>::iterator position;

                                if((position = find_if(newInternal.begin(), 
                                                    newInternal.end(), 
                                                    PlaylistItemCompare(item))) != newInternal.end())
                                {
                                    // need to download it to temp file first
                                    // and then upload it to other card
                                    // in the next stage...
                                    
                                    string itemPath = item->URL();
                                    string downloadPath = tempPath;
                                    downloadPath += DIR_MARKER_STR;

                                    downloadPath.insert(downloadPath.size(), 
                                                        itemPath, 
                                                        itemPath.rfind('/') + 1, 
                                                        itemPath.size());

                                    RioProgressStruct ps;

                                    memset(&ps, 0x00, sizeof(ps));

                                    ps.function = function;
                                    ps.cookie = cookie;
                                    ps.item = item;

                                    if(!rioExternal.RxFile(downloadPath.c_str(), rioProgress, &ps))
                                    {
                                        if(function)
                                        {
                                            PLMEvent event;
        
                                            event.type = kPLMEvent_Error;
                                            event.data.errorData.errorCode = rioExternal.GetErrorID();
                                            event.eventString = "Download failed, ";
                                            event.eventString += rioExternal.GetErrorStr();

                                            function(&event, cookie);
                                        }

                                        if(rioInternal.GetErrorID() == CRIO_ERROR_INTERRUPTED)
                                            result = kError_UserCancel;
                                        else
                                            result = kError_UnknownErr;
                                        break;
                                    }

                                    length = _MAX_PATH;
                                    FilePathToURL(downloadPath.c_str(), path, &length);

                                    (*position)->SetURL(path);
                                }

                                string::size_type pos = item->URL().rfind("/") + 1;
                                const char* cp = item->URL().c_str();

                                if(!rioExternal.RemoveFile(cp + pos))
                                {
                                    if(function)
                                    {
                                        PLMEvent event;
        
                                        event.type = kPLMEvent_Error;
                                        event.data.errorData.errorCode = rioExternal.GetErrorID();
                                        event.eventString = "Delete failed, ";
                                        event.eventString += rioExternal.GetErrorStr();

                                        function(&event, cookie);
                                    }

                                    result = kError_UnknownErr;
                                    break;
                                }

                                delete item;
                                origExternal[index] = NULL;
                            }
                        }
                    }
                }

                // if all is well we add new files
                // to each card
                if(IsntError(result))
                {                 
                    // remove NULLs caused by deletes
                    origInternal.erase(
                        remove(origInternal.begin(), 
                               origInternal.end(), 
                               (PlaylistItem*)NULL), 
                        origInternal.end());

                    origExternal.erase(
                        remove(origExternal.begin(), 
                               origExternal.end(), 
                               (PlaylistItem*)NULL), 
                        origExternal.end());

                    // sync deletes back to the cards
                    rioInternal.TxDirectory();
                    rioExternal.TxDirectory();

                    if(function)
                    {
                        PLMEvent event;

                        event.type = kPLMEvent_Status;
                        event.eventString = "Uploading new files...";

                        function(&event, cookie);
                    }

                    count = newInternal.size();

                    for(index = 0; index < count; index++)
                    {
                        PlaylistItem* item = newInternal[index];

                        if(item->URL().find("file://") != string::npos)
                        {
                            length = _MAX_PATH;

                            URLToFilePath(item->URL().c_str(), path, &length);

                            RioProgressStruct ps;

                            memset(&ps, 0x00, sizeof(ps));

                            ps.function = function;
                            ps.cookie = cookie;
                            ps.item = item;
                            
                            if(!rioInternal.TxFile(path, rioProgress, &ps))
                            {
                                if(function)
                                {
                                    PLMEvent event;
        
                                    event.type = kPLMEvent_Error;
                                    event.data.errorData.errorCode = rioInternal.GetErrorID();
                                    event.eventString = "Upload failed, ";
                                    event.eventString += rioInternal.GetErrorStr();

                                    function(&event, cookie);
                                }

                                if(rioInternal.GetErrorID() == CRIO_ERROR_INTERRUPTED)
                                    result = kError_UserCancel;
                                else
                                    result = kError_UnknownErr;
                                break;
                            }

                            origInternal.push_back(new PlaylistItem(*item));
                        }
                    }

                    if(IsntError(result))
                    {
                        count = newExternal.size();

                        for(index = 0; index < count; index++)
                        {
                            PlaylistItem* item = newExternal[index];

                            if(item->URL().find("file://") != string::npos)
                            {
                                length = _MAX_PATH;

                                URLToFilePath(item->URL().c_str(), path, &length);

                                RioProgressStruct ps;

                                memset(&ps, 0x00, sizeof(ps));

                                ps.function = function;
                                ps.cookie = cookie;
                                ps.item = item;
                            
                                if(!rioExternal.TxFile(path, rioProgress, &ps))
                                {
                                    if(function)
                                    {
                                        PLMEvent event;
        
                                        event.type = kPLMEvent_Error;
                                        event.data.errorData.errorCode = rioExternal.GetErrorID();
                                        event.eventString = "Upload failed, ";
                                        event.eventString += rioExternal.GetErrorStr();

                                        function(&event, cookie);
                                    }

                                    if(rioExternal.GetErrorID() == CRIO_ERROR_INTERRUPTED)
                                        result = kError_UserCancel;
                                    else
                                        result = kError_UnknownErr;
                                    break;
                                }

                                origExternal.push_back(new PlaylistItem(*item));
                            }
                        }
                    }
                }

                // finally put it all in the correct order
                // and we should be done!
                if(IsntError(result))
                {
                    uint32 entryOrder[ CRIO_MAX_DIRENTRY ];

	                count = newInternal.size();

                    if(count)
                    {

                        for(index = 0; index < count; index++)
                        {
                            vector<PlaylistItem*>::iterator position;
                            PlaylistItem* item = newInternal[index];

                            if((position = find_if(origInternal.begin(), 
                                                  origInternal.end(), 
                                                  PlaylistItemCompare(item))) != origInternal.end())
                            {
//#ifdef WIN32
//								distance(origInternal.begin(), position /*, entryOrder[index] */ );
//#else
								entryOrder[index] = distance(origInternal.begin(), position /*, entryOrder[index] */ );
//#endif
                            }

                        }

                        rioInternal.SetFileOrder(entryOrder, count);
                    }

                    count = newExternal.size();

                    if(count)
                    {
                        for(index = 0; index < count; index++)
                        {
                            vector<PlaylistItem*>::iterator position;
                            PlaylistItem* item = newExternal[index];

                            if((position = find_if(origExternal.begin(), 
                                                  origExternal.end(), 
                                                  PlaylistItemCompare(item))) != origExternal.end())
                            {
//#ifdef WIN32
//                                distance(origExternal.begin(), position /*, entryOrder[index] */ );
//#else	                            
								entryOrder[index] = distance(origExternal.begin(), position /*, entryOrder[index] */ );
//#endif

                            }
                        }

                        rioExternal.SetFileOrder(entryOrder, count);
                    }

                    // sync uploads back to the cards
                    rioInternal.TxDirectory();
                    rioExternal.TxDirectory();
                }

                if(function)
                {
                    PLMEvent event;

                    event.type = kPLMEvent_Done;

                    function(&event, cookie);
                }

                // clean up
                length = _MAX_PATH;
                FilePathToURL(tempPath, path, &length);
                strcpy(tempPath, path);

                count = origInternal.size();

                for(index = 0; index < count; index++)
                {
                    PlaylistItem* item = origInternal[index];

                    if(item->URL().find(tempPath) != string::npos)
                    {
                        length = _MAX_PATH;

                        URLToFilePath(item->URL().c_str(), path, &length);

                        remove(path);
                    }

                    delete item;
                }

                count = origExternal.size();

                for(index = 0; index < count; index++)
                {
                    PlaylistItem* item = origExternal[index];

                    if(item->URL().find(tempPath) != string::npos)
                    {
                        length = _MAX_PATH;

                        URLToFilePath(item->URL().c_str(), path, &length);

                        remove(path);
                    }

                    delete item;
                }
 
                
                URLToFilePath(tempPath, path, &length);
                rmdir(path);

                delete [] tempPath;
                delete [] path;
            }
        }       
    }

    return result;
}
Пример #2
0
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;
            char path[_MAX_PATH];
            uint32 length = sizeof(path);

            URLToFilePath(url, path, &length);

            result = kError_FileNoAccess;

            fp = fopen(path, "wb");

            if(fp)
            {
                uint32 index;
                uint32 count;

                count = list->size();

                for(index = 0; index < count; index++)
                {
                    PlaylistItem* item = (*list)[index];

                    length = sizeof(path);

                    if(IsError(URLToFilePath(item->URL().c_str(), path, &length)))
                        fprintf(fp, "%s%s", item->URL().c_str(), LINE_END_MARKER_STR);
                    else
                        fprintf(fp, "%s%s", path, 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;
}