changed: update version strings for beta4
[xbmc.git] / xbmc / utils / DownloadQueue.cpp
blobeff3c46791d33882adb87ff2c1a341dc423ef991
1 /*
2 * Copyright (C) 2005-2008 Team XBMC
3 * http://www.xbmc.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "DownloadQueue.h"
23 #include "Util.h"
24 #include "log.h"
26 #include "FileSystem/File.h"
27 #include "FileSystem/FileCurl.h"
29 using namespace std;
30 using namespace XFILE;
32 WORD CDownloadQueue::m_wNextQueueId = 0;
34 CDownloadQueue::CDownloadQueue(void) : CThread()
36 InitializeCriticalSection(&m_critical);
37 m_bStop = false;
38 m_wQueueId = m_wNextQueueId++;
39 m_dwNextItemId = 0;
40 CThread::Create(false);
43 void CDownloadQueue::OnStartup()
45 SetPriority( GetMinPriority() );
48 CDownloadQueue::~CDownloadQueue(void)
50 DeleteCriticalSection(&m_critical);
54 TICKET CDownloadQueue::RequestContent(const CStdString& aUrl, IDownloadQueueObserver* aObserver)
56 EnterCriticalSection(&m_critical);
58 TICKET ticket(m_wQueueId, m_dwNextItemId++);
60 Command request = {ticket, aUrl, "", aObserver};
61 m_queue.push(request);
63 LeaveCriticalSection(&m_critical);
64 return request.ticket;
67 TICKET CDownloadQueue::RequestFile(const CStdString& aUrl, const CStdString& aFilePath, IDownloadQueueObserver* aObserver)
69 EnterCriticalSection(&m_critical);
71 TICKET ticket(m_wQueueId, m_dwNextItemId++);
73 Command request = {ticket, aUrl, aFilePath, aObserver};
74 m_queue.push(request);
76 LeaveCriticalSection(&m_critical);
77 return request.ticket;
80 void CDownloadQueue::CancelRequests(IDownloadQueueObserver *aObserver)
82 EnterCriticalSection(&m_critical);
84 CLog::Log(LOGDEBUG, "CancelRequests from observer at %p", aObserver);
85 // run through our queue, and create a new queue with the requests
86 // from aObserver NULL'd out.
87 queue<Command> newQueue;
88 while (m_queue.size())
90 Command request = m_queue.front();
91 m_queue.pop();
92 if (request.observer == aObserver)
93 request.observer = NULL;
94 newQueue.push(request);
96 m_queue = newQueue;
97 LeaveCriticalSection(&m_critical);
100 TICKET CDownloadQueue::RequestFile(const CStdString& aUrl, IDownloadQueueObserver* aObserver)
102 EnterCriticalSection(&m_critical);
104 CLog::Log(LOGDEBUG, "RequestFile from observer at %p", aObserver);
105 // create a temporary destination
106 CStdString strExtension;
107 CUtil::GetExtension(aUrl, strExtension);
109 TICKET ticket(m_wQueueId, m_dwNextItemId++);
111 CStdString strFilePath;
112 strFilePath.Format("special://temp/q%d-item%u%s", ticket.wQueueId, ticket.dwItemId, strExtension.c_str());
114 Command request = {ticket, aUrl, strFilePath, aObserver};
115 m_queue.push(request);
117 LeaveCriticalSection(&m_critical);
118 return request.ticket;
121 VOID CDownloadQueue::Flush()
123 EnterCriticalSection(&m_critical);
125 m_queue.empty();
127 LeaveCriticalSection(&m_critical);
130 void CDownloadQueue::Process()
132 CLog::Log(LOGNOTICE, "DownloadQueue ready.");
134 CFileCurl http;
135 bool bSuccess;
137 while ( !m_bStop )
139 while ( CDownloadQueue::Size() > 0 )
141 EnterCriticalSection(&m_critical);
143 // get the first item, but don't pop it from our queue
144 // so that the download can be interrupted
145 Command request = m_queue.front();
147 LeaveCriticalSection(&m_critical);
149 bool bFileRequest = request.content.length() > 0;
150 DWORD dwSize = 0;
152 if (bFileRequest)
154 CFile::Delete(request.content);
155 bSuccess = http.Download(request.location, request.content, &dwSize);
157 else
159 bSuccess = http.Get(request.location, request.content);
162 // now re-grab the item as we may have cancelled our download
163 // while we were working
164 EnterCriticalSection(&m_critical);
166 request = m_queue.front();
167 m_queue.pop();
169 // if the request has been cancelled our observer will be NULL
170 if (NULL != request.observer)
174 if (bFileRequest)
176 request.observer->OnFileComplete(request.ticket, request.content, dwSize,
177 bSuccess ? IDownloadQueueObserver::Succeeded : IDownloadQueueObserver::Failed );
179 else
181 request.observer->OnContentComplete(request.ticket, request.content,
182 bSuccess ? IDownloadQueueObserver::Succeeded : IDownloadQueueObserver::Failed );
185 catch (...)
187 CLog::Log(LOGERROR, "exception while updating download observer.");
189 if (bFileRequest)
191 CFile::Delete(request.content);
195 LeaveCriticalSection(&m_critical);
198 Sleep(500);
201 CLog::Log(LOGNOTICE, "DownloadQueue terminated.");
204 INT CDownloadQueue::Size()
206 EnterCriticalSection(&m_critical);
208 int sizeOfQueue = m_queue.size();
210 LeaveCriticalSection(&m_critical);
212 return sizeOfQueue;