www.pudn.com > SharpDownload(FTP¼°WEBÏÂÔØ).zip > FilePart.cs


using System; 
using System.Diagnostics; 
using System.Threading; 
using System.Runtime.Remoting; 
using System.Runtime.Remoting.Contexts; 
using System.Runtime.Remoting.Messaging; 
 
namespace SharpDownload 
{ 
	///  
	/// The file part class handles individual part downloads. 
	/// It initiates connections with servers and manages data downloading. 
	///  
	public class FilePart 
	{ 
		private string sourceFile; 
		private string destinationFile; 
		private long byteOffset; 
		private long partSize; 
		private long bytesDownloaded; 
		private int partNumber; 
		private ProtocolClient protocolClient; 
		private bool downloadComplete = false; 
		private bool isLastPart = false; 
 
		private FileDownload.FileDownloadCommandEnum command = FileDownload.FileDownloadCommandEnum.NoCommand; 
 
		private const string MODULE_NAME = "FilePart"; 
 
		///  
		/// Default constructor 
		///  
		/// The number of this part within the File Download 
		public FilePart(int PartNumber) 
		{ 
			this.partNumber = PartNumber; 
		} 
 
		///  
		/// Byte offset property 
		///  
		public long ByteOffset 
		{ 
			get 
			{ 
				return byteOffset; 
			} 
			set 
			{ 
				byteOffset = value; 
			} 
		} 
		 
		///  
		/// Part size property 
		///  
		public long PartSize 
		{ 
			get 
			{ 
				return partSize; 
			} 
			set 
			{ 
				partSize = value; 
			} 
		} 
		 
		///  
		/// Bytes downloaded property 
		///  
		public long BytesDownloaded 
		{ 
			get 
			{ 
				return bytesDownloaded; 
			} 
			set 
			{ 
				bytesDownloaded = value; 
			} 
		} 
 
		///  
		/// Protocol client used for downloading and comms 
		///  
		public ProtocolClient ProtocolClient 
		{ 
			get 
			{ 
				return protocolClient; 
			} 
		} 
 
		///  
		/// Source file to download 
		///  
		public string SourceFile 
		{ 
			get 
			{ 
				return sourceFile; 
			} 
			set 
			{ 
				sourceFile=value; 
			} 
		} 
 
		///  
		/// Destination file to download to 
		///  
		public string DestinationFile 
		{ 
			get 
			{ 
				return destinationFile; 
			} 
			set 
			{ 
				destinationFile=value; 
			} 
		} 
 
		///  
		/// The part number of the File Download 
		///  
		public int PartNumber 
		{ 
			get 
			{ 
				return partNumber; 
			} 
			set 
			{ 
				partNumber = value; 
			} 
		} 
 
		///  
		/// Flag to mark the download as completed 
		///  
		public bool IsDownloadComplete 
		{ 
			get 
			{ 
				return downloadComplete; 
			} 
		} 
 
		///  
		/// Flag if this part is the last part 
		///  
		public bool IsLastPart 
		{ 
			get 
			{ 
				return isLastPart; 
			} 
			set 
			{ 
				isLastPart = value; 
			} 
		} 
 
		public FileDownload.FileDownloadCommandEnum Command 
		{ 
			get 
			{ 
				return command; 
			} 
			set 
			{ 
				command = value; 
				// Set the protocol client value as well 
				if (protocolClient!=null) 
				{ 
					protocolClient.Command = value; 
				} 
			} 
		} 
 
		///  
		/// Asynchronous download call 
		///  
		/// DownloadInfo component 
		/// true if download started; false otherwise 
		public bool AsyncDownload(DownloadInfo downloadInfo) 
		{ 
			// Call factory create 
			protocolClient = ProtocolClient.GetProtocolClient(downloadInfo); 
 
			// Set up the event handlers 
			protocolClient.DownloadStartedEvent += new ProtocolClient.DownloadStartedEventHandler(PartDownloadStarted); 
			protocolClient.DataReceivedEvent += new ProtocolClient.DataReceivedEventHandler(PartDataReceived); 
			 
			// Start the transfer 
			protocolClient.BeginDownload(this.SourceFile, this.DestinationFile, downloadInfo.ResumeSupported, this.ByteOffset, this.PartSize, this.PartSize, this.IsLastPart, new AsyncCallback(PartDownloadFinished)); 
 
			return true; 
		} 
 
		#region PartDownloadStarted Event 
		///  
		/// Part download started event arguments 
		///  
		public class PartDownloadStartedEventArgs : EventArgs 
		{ 
			private readonly int partNumber; 
			///  
			/// PartDownloadStarted event arguments 
			///  
			/// Size of the file in Bytes 
			public PartDownloadStartedEventArgs (int PartNumber) 
			{ 
				partNumber = PartNumber; 
			} 
			///  
			/// Public read-only size of the file in Bytes 
			///  
			public int PartNumber 
			{ 
				get 
				{ 
					return partNumber; 
				} 
			} 
		} 
		///  
		/// Delegate for Part Download Started Event 
		///  
		public delegate void PartDownloadStartedEventHandler(FilePart sender, PartDownloadStartedEventArgs e); 
		///  
		/// The Part Download Started Event is raised when the download starts 
		///  
		public event PartDownloadStartedEventHandler PartDownloadStartedEvent; 
		///  
		/// OnPartDownloadStartedEvent 
		///  
		/// PartDownloadStartedEventArgs 
		protected virtual void OnPartDownloadStartedEvent(PartDownloadStartedEventArgs e) 
		{ 
			// Check if any events have been bound 
			if (PartDownloadStartedEvent != null) 
			{ 
				PartDownloadStartedEvent(this, e); 
			} 
		} 
 
		#endregion 
 
		#region PartDownloadStatus Event 
		///  
		/// Part download statuses 
		///  
		public enum PartDownloadStatusEnum 
		{ 
			///  
			/// The file part is initialising 
			///  
			Initialising, 
			///  
			/// The file part has completed initialising 
			///  
			Initialised, 
			///  
			/// The file part is logging in to the server 
			///  
			LoggingIn, 
			///  
			/// The file part has logged in 
			///  
			LoggedIn, 
			///  
			/// The file part is currently receiving data 
			///  
			ReceivingFile, 
			///  
			/// The file part has finished receiving 
			///  
			FileReceived, 
			///  
			/// The file part is closing 
			///  
			Closing, 
			///  
			/// The file part has closed 
			///  
			Closed 
		} 
 
		///  
		/// Part download status event arguments 
		///  
		public class PartDownloadStatusEventArgs : EventArgs 
		{ 
			private PartDownloadStatusEnum partDownloadStatus; 
			///  
			/// PartDownloadStatus event arguments 
			///  
			/// Current part download status 
			public PartDownloadStatusEventArgs (PartDownloadStatusEnum currentPartDownloadStatus) 
			{ 
				partDownloadStatus = currentPartDownloadStatus; 
			} 
			///  
			/// Public read-only property returns the download status 
			///  
			public PartDownloadStatusEnum PartDownloadStatus 
			{ 
				get 
				{ 
					return partDownloadStatus; 
				} 
			} 
		} 
		///  
		/// Delegate for Part Download Started Event 
		///  
		public delegate void PartDownloadStatusEventHandler(FilePart sender, PartDownloadStatusEventArgs e); 
		///  
		/// The Part Download Started Event is raised when the download starts 
		///  
		public event PartDownloadStatusEventHandler PartDownloadStatusEvent; 
		///  
		/// OnPartDownloadStatusEvent 
		///  
		/// PartDownloadStatusEventArgs 
		protected virtual void OnPartDownloadStatusEvent(PartDownloadStatusEventArgs e) 
		{ 
			// Check if any events have been attached 
			if (PartDownloadStatusEvent != null) 
			{ 
				PartDownloadStatusEvent(this, e); 
			} 
		} 
 
		#endregion 
 
		#region PartDataReceived Event 
		///  
		/// Part data received event arguments 
		///  
		public class PartDataReceivedEventArgs : EventArgs 
		{ 
			private readonly long totalPartDataReceived; 
			///  
			/// Default constructor 
			///  
			/// Total amount of data in bytes received 
			public PartDataReceivedEventArgs (long totalPartData) 
			{ 
				this.totalPartDataReceived = totalPartData; 
			} 
			///  
			/// Read-only param to get the total number of bytes received 
			///  
			public long TotalDataReceived 
			{ 
				get 
				{ 
					return totalPartDataReceived; 
				} 
			} 
		} 
		///  
		/// Delegate for Data Received Event 
		///  
		public delegate void PartDataReceivedEventHandler(FilePart sender, PartDataReceivedEventArgs e); 
		///  
		/// The Data Received Event is raised when data is received in the download module. 
		///  
		public event PartDataReceivedEventHandler PartDataReceivedEvent; 
		///  
		/// OnPartDataReceivedEvent 
		///  
		/// PartDataReceivedEventArgs 
		protected virtual void OnPartDataReceivedEvent(PartDataReceivedEventArgs e) 
		{ 
			// Check if any events have been attached 
			if (PartDataReceivedEvent != null) 
			{ 
				PartDataReceivedEvent(this, e); 
			} 
		} 
		#endregion 
 
		#region PartDownloadStopped Event 
		///  
		/// Part download stopped event arguments 
		///  
		public class PartDownloadStoppedEventArgs : EventArgs 
		{ 
			private ProtocolClient.DownloadResult downloadResult; 
			///  
			/// Public default constructor 
			///  
			public PartDownloadStoppedEventArgs (ProtocolClient.DownloadResult Result) 
			{ 
				downloadResult = Result; 
			} 
			public ProtocolClient.DownloadResult Result 
			{ 
				get 
				{ 
					return downloadResult; 
				} 
			} 
		} 
		///  
		/// Delegate for Part Download Started Event 
		///  
		public delegate void PartDownloadStoppedEventHandler(FilePart sender, PartDownloadStoppedEventArgs e); 
		///  
		/// The Part Download Started Event is raised when the download starts 
		///  
		public event PartDownloadStoppedEventHandler PartDownloadStoppedEvent; 
		///  
		/// OnPartDownloadStoppedEvent 
		///  
		/// PartDownloadStoppedEventArgs 
		protected virtual void OnPartDownloadStoppedEvent(PartDownloadStoppedEventArgs e) 
		{ 
			// Check if any events have been attached 
			if (PartDownloadStoppedEvent != null) 
			{ 
				PartDownloadStoppedEvent(this, e); 
			} 
		} 
		#endregion 
 
		#region PartDownloadFinished Event 
		///  
		/// Part download started event arguments 
		///  
		public class PartDownloadFinishedEventArgs : EventArgs 
		{ 
			///  
			/// Public default constructor 
			///  
			public PartDownloadFinishedEventArgs () 
			{ 
			} 
		} 
		///  
		/// Delegate for Part Download Started Event 
		///  
		public delegate void PartDownloadFinishedEventHandler(FilePart sender, PartDownloadFinishedEventArgs e); 
		///  
		/// The Part Download Started Event is raised when the download starts 
		///  
		public event PartDownloadFinishedEventHandler PartDownloadFinishedEvent; 
		///  
		/// OnPartDownloadFinishedEvent 
		///  
		/// PartDownloadFinishedEventArgs 
		protected virtual void OnPartDownloadFinishedEvent(PartDownloadFinishedEventArgs e) 
		{ 
			// Check if any events have been attached 
			if (PartDownloadFinishedEvent != null) 
			{ 
				PartDownloadFinishedEvent(this, e); 
			} 
		} 
 
		#endregion 
 
		#region Event handlers 
		// Part download started event handler 
		private void PartDownloadStarted(ProtocolClient sender, ProtocolClient.DownloadStartedEventArgs e) 
		{ 
			try 
			{ 
				OnPartDownloadStartedEvent(new PartDownloadStartedEventArgs(this.PartNumber)); 
			} 
			catch (Exception ePartDownloadStartedEvent) 
			{ 
				Debug.WriteLine("Exception occurred in PartDownloadStarted [" + ePartDownloadStartedEvent.Message + "]", MODULE_NAME); 
			} 
		} 
 
		// Data received event handler 
		private void PartDataReceived(ProtocolClient sender, ProtocolClient.DataReceivedEventArgs e) 
		{ 
			try 
			{ 
				this.BytesDownloaded = e.TotalDataReceived; 
				OnPartDataReceivedEvent(new PartDataReceivedEventArgs(this.BytesDownloaded)); 
			} 
			catch (Exception ePartDataReceivedEvent) 
			{ 
				Debug.WriteLine("Exception occurred in PartDataReceived [" + ePartDataReceivedEvent.Message + "]", MODULE_NAME); 
			} 
		} 
 
		// Download finished callback 
		private void PartDownloadFinished(IAsyncResult result) 
		{ 
			try 
			{ 
				// Check the callback result 
				AsyncResult aResult = (AsyncResult)result; 
				ProtocolClient.DownloadFileNameFileNameResumeOffsetStopAtFileSizeLastPartCallback asyncDelegate = (ProtocolClient.DownloadFileNameFileNameResumeOffsetStopAtFileSizeLastPartCallback)aResult.AsyncDelegate; 
				ProtocolClient.DownloadResult returnVal = asyncDelegate.EndInvoke(aResult); 
 
				Debug.WriteLine("PartDownloadFinished callback, result was: " + returnVal, MODULE_NAME + "[" + this.PartNumber.ToString() + "]"); 
 
				if (this.PartSize!=this.BytesDownloaded) Debug.WriteLine("WARNING - file part size mismatch [" + this.BytesDownloaded + " bytes, expected " + this.PartSize + " bytes]", MODULE_NAME + "[" + this.PartNumber + "]"); 
 
				// Close the client 
				ProtocolClient protocolClientReturned = (ProtocolClient)result.AsyncState; 
				if ( protocolClientReturned != null ) protocolClientReturned.Close(); 
				protocolClientReturned = null; 
 
				// Check the return value 
				switch (returnVal) 
				{ 
					case ProtocolClient.DownloadResult.Finished: 
						// Set the download to completed 
						this.downloadComplete = true; 
						// Raise the download finished event 
						OnPartDownloadFinishedEvent(new PartDownloadFinishedEventArgs()); 
						break; 
					case ProtocolClient.DownloadResult.Error: 
						// Set the download to NOT completed 
						this.downloadComplete = false; 
						OnPartDownloadStoppedEvent(new PartDownloadStoppedEventArgs(returnVal)); 
						break; 
					case ProtocolClient.DownloadResult.Cancelled: 
						// Set the download to NOT completed 
						this.downloadComplete = false; 
						// Raise the download cancelled event 
						OnPartDownloadStoppedEvent(new PartDownloadStoppedEventArgs(returnVal)); 
						break; 
					case ProtocolClient.DownloadResult.Paused: 
						// Set the download to NOT completed 
						this.downloadComplete = false; 
						// Raise the download cancelled event 
						OnPartDownloadStoppedEvent(new PartDownloadStoppedEventArgs(returnVal)); 
						break; 
					default: 
						break; 
				} 
 
			} 
			catch (Exception e) 
			{ 
				// Log the error 
				Debug.WriteLine("An error occurred while downloading the file. [" + e.Message + "]", MODULE_NAME); 
			} 
		}  
		 
		#endregion 
	} 
}