31 #include <nsStringGlue.h>
32 #include <nsIInputStream.h>
33 #include <nsIResumableChannel.h>
34 #include <nsIChannel.h>
36 #include <nsIFileStreams.h>
37 #include <nsIIOService.h>
38 #include <nsNetUtil.h>
44 extern PRLogModuleInfo* gMetadataLog;
58 m_BufDeadZoneStart( 0 ),
59 m_BufDeadZoneEnd( 0 ),
61 m_Completed( PR_FALSE )
66 sbMetadataChannel::~sbMetadataChannel()
76 if ( ! channel || ! handler )
77 return NS_ERROR_NULL_POINTER;
87 nsCOMPtr<nsIRequest> request = do_QueryInterface(m_Channel);
88 PRUint32 loadFlags = nsIRequest::INHIBIT_CACHING |
89 nsIRequest::INHIBIT_PERSISTENT_CACHING |
90 nsIRequest::LOAD_BYPASS_CACHE;
91 rv = request->SetLoadFlags(loadFlags);
92 NS_ASSERTION(NS_SUCCEEDED(rv),
"Setting load flags failed :( Watch out, app will deadlock.");
98 NS_ENSURE_TRUE(ir, NS_ERROR_OUT_OF_MEMORY);
100 rv = m_Channel->SetNotificationCallbacks(ir);
101 NS_ENSURE_SUCCESS(rv, rv);
103 return m_Channel->AsyncOpen(
this, handler );
107 NS_IMETHODIMP sbMetadataChannel::Close()
111 PRBool pendingRequest = PR_FALSE;
112 m_Channel->IsPending(&pendingRequest);
119 m_BufDeadZoneStart = 0;
120 m_BufDeadZoneEnd = 0;
128 NS_IMETHODIMP sbMetadataChannel::SetPos(PRUint64
pos)
137 if (m_BufDeadZoneStart)
138 return NS_ERROR_UNEXPECTED;
143 nsCOMPtr<nsIResumableChannel> testing_to_see_if_this_exists_but_never_going_to_use( do_QueryInterface(m_Channel, &rv) );
144 if ( NS_FAILED( rv ) )
return NS_ERROR_INVALID_ARG;
147 nsCOMPtr<nsIURI> pURI;
148 rv = m_Channel->GetURI( getter_AddRefs(pURI) );
149 NS_ENSURE_SUCCESS( rv, rv );
159 nsCOMPtr<nsIIOService> pIOService = do_GetIOService(&rv);
160 NS_ENSURE_SUCCESS( rv, rv );
161 rv = pIOService->NewChannelFromURI(pURI, getter_AddRefs(m_Channel));
162 NS_ENSURE_SUCCESS( rv, rv );
165 nsCOMPtr<nsIResumableChannel> resume( do_QueryInterface(m_Channel, &rv) );
166 NS_ENSURE_SUCCESS( rv, rv );
169 rv = resume->ResumeAt( pos, NS_LITERAL_CSTRING(
"") );
170 NS_ENSURE_SUCCESS( rv, rv );
171 rv = m_Channel->AsyncOpen(
this, m_Handler );
172 NS_ENSURE_SUCCESS( rv, rv );
175 m_BufDeadZoneStart = m_Buf;
176 m_BufDeadZoneEnd = m_Buf =
pos;
184 if ( m_BufDeadZoneStart && pos >= m_BufDeadZoneStart && pos < m_BufDeadZoneEnd )
186 NS_WARNING(
"****** METADATACHANNEL ****** Can't seek into the deadzone");
187 return NS_ERROR_UNEXPECTED;
196 NS_IMETHODIMP sbMetadataChannel::GetPos(PRUint64 *_retval)
199 return NS_ERROR_NULL_POINTER;
207 NS_IMETHODIMP sbMetadataChannel::GetBuf(PRUint64 *_retval)
210 return NS_ERROR_NULL_POINTER;
218 NS_IMETHODIMP sbMetadataChannel::GetSize(PRUint64 *_retval)
221 return NS_ERROR_NULL_POINTER;
225 NS_ASSERTION(m_Channel,
"sbMetadataChannel::GetSize called without m_Channel set!");
228 m_Channel->GetContentLength( &ret );
230 *_retval = (PRInt64)ret;
236 NS_IMETHODIMP sbMetadataChannel::Skip(PRUint64
skip)
238 return SetPos( m_Pos + skip );
242 NS_IMETHODIMP sbMetadataChannel::Read(
char * out_buf, PRUint32 len, PRUint32 *_retval)
246 return NS_ERROR_NULL_POINTER;
247 if ( m_Pos + len >= m_Buf )
248 return NS_ERROR_UNEXPECTED;
252 for ( PRUint32 remaining = len,
count = (PRUint32)-1; remaining &&
count; remaining -=
count, m_Pos +=
count, out_buf +=
count, *_retval +=
count )
255 PRUint32
left = (PRUint32)( BLOCK_SIZE - POS(m_Pos) );
256 count =
std::min( remaining, left );
257 char *
buf = BUF(m_Pos);
258 memcpy( out_buf, buf, count );
264 NS_IMETHODIMP sbMetadataChannel::ReadChar(
char *_retval)
267 if ( m_Pos + 1 >= m_Buf )
268 return NS_ERROR_UNEXPECTED;
271 Read( _retval, 1, &count );
276 NS_IMETHODIMP sbMetadataChannel::ReadInt32(PRInt32 *_retval)
279 if ( m_Pos + 4 >= m_Buf )
280 return NS_ERROR_UNEXPECTED;
283 Read( (
char *)_retval, 4, &count );
287 *_retval = ( ( *_retval & 0xFF000000 ) >> 24 ) |
288 ( ( *_retval & 0x00FF0000 ) >> 8 ) |
289 ( ( *_retval & 0x0000FF00 ) << 8 ) |
290 ( ( *_retval & 0x000000FF ) << 24 );
296 NS_IMETHODIMP sbMetadataChannel::ReadInt64(PRInt64 *_retval)
299 if ( m_Pos + 8 >= m_Buf )
300 return NS_ERROR_UNEXPECTED;
303 Read( (
char *)_retval, 8, &count );
308 *_retval = ( ( *_retval & (
long long)0xFF00000000000000 ) >> 56 ) |
309 ( ( *_retval & (
long long)0x00FF000000000000 ) >> 40 ) |
310 ( ( *_retval & (
long long)0x0000FF0000000000 ) >> 24 ) |
311 ( ( *_retval & (
long long)0x000000FF00000000 ) >> 8 ) |
312 ( ( *_retval & 0x00000000FF000000 ) << 8 ) |
313 ( ( *_retval & 0x0000000000FF0000 ) << 24 ) |
314 ( ( *_retval & 0x000000000000FF00 ) << 40 ) |
315 ( ( *_retval & 0x00000000000000FF ) << 56 );
323 NS_IMETHODIMP sbMetadataChannel::GetSeekable(PRBool *_retval)
326 return NS_ERROR_NULL_POINTER;
334 NS_IMETHODIMP sbMetadataChannel::GetCompleted(PRBool *_retval)
337 return NS_ERROR_NULL_POINTER;
339 *_retval = m_Completed;
345 sbMetadataChannel::OnDataAvailable(nsIRequest *aRequest,
347 nsIInputStream *inStr,
348 PRUint32 sourceOffset,
352 if ( ! aRequest || ! ctxt || ! inStr )
353 return NS_ERROR_NULL_POINTER;
354 if ( m_Buf != sourceOffset )
355 return NS_ERROR_UNEXPECTED;
358 for ( PRUint32 remaining = count,
read = (PRUint32)-1; remaining &&
read; remaining -=
read, m_Buf +=
read )
361 PRUint32 left = (PRUint32)( BLOCK_SIZE - POS(m_Buf) );
362 PRUint32 len =
std::min( remaining, left );
363 char *
buf = BUF(m_Buf);
364 inStr->Read( buf, len, &read );
371 if ( m_Buf >= BLOCK_SIZE )
374 nsCOMPtr<sbIMetadataHandler>
handler( do_QueryInterface(ctxt) );
377 handler->OnChannelData(
this );
378 PRBool complete = PR_FALSE;
379 nsresult rv = handler->GetCompleted( &complete );
380 if ( NS_FAILED( rv ) || complete )
392 sbMetadataChannel::OnStartRequest(nsIRequest *aRequest,
396 aRequest->GetStatus( &result );
401 sbMetadataChannel::OnStopRequest(nsIRequest *aRequest,
406 nsresult rv, request_status;
407 rv = aRequest->GetStatus( &request_status );
408 NS_ENSURE_SUCCESS(rv, rv);
413 m_Completed = PR_TRUE;
415 nsCOMPtr<sbIMetadataHandler>
handler( do_QueryInterface(ctxt, &rv) );
416 NS_ENSURE_SUCCESS(rv, rv);
419 handler->OnChannelData(
this );
425 sbMetadataChannel::SetRedirectedChannel(
nsIChannel* aChannel)
427 m_Channel = aChannel;
438 mMetadataChannel = aMetadataChannel;
441 sbMetadataChannelEventSink::~sbMetadataChannelEventSink()
446 sbMetadataChannelEventSink::OnChannelRedirect(
nsIChannel* oldChannel,
452 rv = mMetadataChannel->SetRedirectedChannel(newChannel);
453 NS_ENSURE_SUCCESS(rv, rv);
459 sbMetadataChannelEventSink::GetInterface(
const nsIID&
uuid,
void** aResult)
sbDeviceFirmwareAutoCheckForUpdate prototype flags
sbOSDControlService prototype QueryInterface
const nsIInterfaceRequestor
NS_IMPL_THREADSAFE_ISUPPORTS3(sbAlbumArtFetcherSet, sbIAlbumArtFetcherSet, sbIAlbumArtFetcher, sbIAlbumArtListener) NS_IMETHODIMP sbAlbumArtFetcherSet
If true, only attempt to fetch album art from local sources.