2 * Copyright (C) 2005-2008 Team XBMC
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)
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"
26 #include "FileSystem/File.h"
27 #include "FileSystem/FileCurl.h"
30 using namespace XFILE
;
32 WORD
CDownloadQueue::m_wNextQueueId
= 0;
34 CDownloadQueue::CDownloadQueue(void) : CThread()
36 InitializeCriticalSection(&m_critical
);
38 m_wQueueId
= m_wNextQueueId
++;
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();
92 if (request
.observer
== aObserver
)
93 request
.observer
= NULL
;
94 newQueue
.push(request
);
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
);
127 LeaveCriticalSection(&m_critical
);
130 void CDownloadQueue::Process()
132 CLog::Log(LOGNOTICE
, "DownloadQueue ready.");
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;
154 CFile::Delete(request
.content
);
155 bSuccess
= http
.Download(request
.location
, request
.content
, &dwSize
);
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();
169 // if the request has been cancelled our observer will be NULL
170 if (NULL
!= request
.observer
)
176 request
.observer
->OnFileComplete(request
.ticket
, request
.content
, dwSize
,
177 bSuccess
? IDownloadQueueObserver::Succeeded
: IDownloadQueueObserver::Failed
);
181 request
.observer
->OnContentComplete(request
.ticket
, request
.content
,
182 bSuccess
? IDownloadQueueObserver::Succeeded
: IDownloadQueueObserver::Failed
);
187 CLog::Log(LOGERROR
, "exception while updating download observer.");
191 CFile::Delete(request
.content
);
195 LeaveCriticalSection(&m_critical
);
201 CLog::Log(LOGNOTICE
, "DownloadQueue terminated.");
204 INT
CDownloadQueue::Size()
206 EnterCriticalSection(&m_critical
);
208 int sizeOfQueue
= m_queue
.size();
210 LeaveCriticalSection(&m_critical
);