using System; using System.Net; using System.IO; using System.Threading; namespace RJH.Utils.WebDownload { public delegate void DownloadProgressHandler( int bytesRead, int totalBytes ); // The RequestState class passes data across async calls. public class DownloadInfo { const int BufferSize = 1024; public byte[] BufferRead; public bool useFastBuffers; public byte[] dataBufferFast; public System.Collections.ArrayList dataBufferSlow; public int dataLength; public int bytesProcessed; public WebRequest Request; public Stream ResponseStream; public DownloadProgressHandler ProgressCallback; public DownloadInfo() { BufferRead = new byte[ BufferSize ]; Request = null; dataLength = -1; bytesProcessed = 0; useFastBuffers = true; } } // ClientGetAsync issues the async request. public class WebDownload { public ManualResetEvent allDone = new ManualResetEvent( false ); const int BUFFER_SIZE = 1024; public volatile bool CancelDownload = false; public byte[] Download( string url, DownloadProgressHandler progressCB ) { // Ensure flag set correctly. allDone.Reset(); // Get the URI from the command line. Uri httpSite = new Uri( url ); // Create the request object. WebRequest req = WebRequest.Create( httpSite ); // Create the state object. DownloadInfo info = new DownloadInfo(); // Put the request into the state object so it can be passed around. info.Request = req; // Assign the callbacks info.ProgressCallback += progressCB; // Issue the async request. IAsyncResult r = (IAsyncResult) req.BeginGetResponse( new AsyncCallback( ResponseCallback ), info ); // Wait until the ManualResetEvent is set so that the application // does not exit until after the callback is called. allDone.WaitOne(); // Pass back the downloaded information. if ( info.useFastBuffers ) return info.dataBufferFast; else { byte[] data = new byte[ info.dataBufferSlow.Count ]; for ( int b=0; b 0 ) { if ( info.useFastBuffers ) { System.Array.Copy( info.BufferRead, 0, info.dataBufferFast, info.bytesProcessed, bytesRead ); } else { for ( int b=0; b