public SharedFileInfo(Stream s) { BincodingDecoder decoder = new BincodingDecoder(s, "FI"); while (true) { Bincoding value = decoder.DecodeNext(); if (value.Type == BincodingType.NULL) { break; } KeyValuePair <string, Bincoding> pair = value.GetKeyValuePair(); switch (pair.Key) { case "file_path": _filePath = pair.Value.GetStringValue(); break; case "file_metadata": _fileMetaData = new SharedFileMetaData(pair.Value.GetValueStream()); break; case "state": _state = (SharedFileState)pair.Value.GetByteValue(); break; case "block_available": _blockAvailable = pair.Value.Value; break; } } }
public SharedFileInfo(string filePath, SharedFileMetaData fileMetaData, byte[] blockAvailable, SharedFileState state) { _filePath = filePath; _fileMetaData = fileMetaData; _blockAvailable = blockAvailable; _state = state; }
public void Pause() { if (_state != SharedFileState.Paused) { _state = SharedFileState.Paused; Stop(); //announce no participation in chats SendFileShareUnparticipate(); } }
private void StartSharing() { if (_state != SharedFileState.Sharing) { _state = SharedFileState.Sharing; //send advertisement SendFileAdvertisement(); //start file transfer speed calculator _fileTransferSpeedCalculator = new Timer(FileTransferSpeedCalculatorAsync, null, 1000, 1000); } }
private void OnDownloadComplete() { //verify if all blocks are available for (int i = 0; i < _blockAvailable.Length; i++) { if (_blockAvailable[i] == FILE_BLOCK_NOT_AVAILABLE) { return; //found a pending block; do nothing } } //set variables _isComplete = true; _state = SharedFileState.Sharing; _availableBlocksCount = _blockAvailable.Length; //rename and open file again in read shared mode string filePath = _fileStream.Name; _fileStream.Close(); File.SetLastWriteTimeUtc(filePath, _metaData.LastModified); string newFilePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); File.Move(filePath, newFilePath); _fileStream = new FileStream(newFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); //remove seeders _seedersLock.EnterWriteLock(); try { _seeders.Clear(); } finally { _seedersLock.ExitWriteLock(); } //announce advertisement for the complete file to all chats available with same file SendBroadcastFileAdvertisement(); //notify event to UI if (FileDownloaded != null) { RaiseEventFileDownloaded(); } }
public void Pause() { if (_state != SharedFileState.Paused) { _state = SharedFileState.Paused; Stop(); //announce no participation in chats SendBroadcastFileShareUnparticipate(); if (FilePaused != null) { RaiseEventFilePaused(); } } }
private void StartDownload() { if (_state != SharedFileState.Downloading) { _state = SharedFileState.Downloading; //get file if (_fileStream == null) { BitChatProfile profile; lock (_chats) { profile = _chats[0].Profile; } //find file name string filePath = Path.Combine(profile.DownloadFolder, _metaData.FileName); int nameCount = 0; while (File.Exists(filePath)) { if (nameCount > 10000) { throw new BitChatException("Cannot download file as local file name not available."); } nameCount++; filePath = Path.Combine(profile.DownloadFolder, Path.GetFileNameWithoutExtension(_metaData.FileName) + " [" + nameCount + "]" + Path.GetExtension(_metaData.FileName)); } //create file _fileStream = new FileStream(filePath + ".downloading", FileMode.Create, FileAccess.ReadWrite); //pre-allocate file _fileStream.SetLength(_metaData.FileSize); //init block available _blockAvailable = new byte[_blockAvailable.Length]; _availableBlocksCount = 0; } //list all pending blocks if (_pendingBlocks == null) { _pendingBlocks = new List <int>(_blockAvailable.Length); _rndPendingBlock = new Random(DateTime.UtcNow.Second); } else { _pendingBlocks.Clear(); } for (int i = 0; i < _blockAvailable.Length; i++) { if (_blockAvailable[i] == FILE_BLOCK_NOT_AVAILABLE) { _pendingBlocks.Add(i); } } if (_pendingBlocks.Count > 0) { //announce file sharing participation in chats SendBroadcastFileShareParticipate(); //start block download int totalDownloaders = FILE_BLOCK_DOWNLOAD_THREADS; if (_pendingBlocks.Count < totalDownloaders) { totalDownloaders = _pendingBlocks.Count; } _downloaders = new List <FileBlockDownloader>(totalDownloaders); lock (_downloaders) { for (int i = 0; i < totalDownloaders; i++) { _downloaders.Add(new FileBlockDownloader(this)); } } //start file transfer speed calculator _fileTransferSpeedCalculator = new Timer(FileTransferSpeedCalculatorAsync, null, 1000, 1000); if (FileDownloadStarted != null) { RaiseEventFileDownloadStarted(); } } else { OnDownloadComplete(); } } }
internal static SharedFile LoadFile(string filePath, SharedFileMetaData metaData, byte[] blockAvailable, SharedFileState state, SynchronizationContext syncCxt) { //check if file already shared lock (_sharedFiles) { SharedFile sharedFile; if (_sharedFiles.ContainsKey(metaData.FileID)) { sharedFile = _sharedFiles[metaData.FileID]; } else { if (state == SharedFileState.Advertisement) { sharedFile = new SharedFile(null, metaData, new byte[metaData.BlockHash.Length], 0, syncCxt); _sharedFiles.Add(metaData.FileID, sharedFile); sharedFile._state = SharedFileState.Advertisement; } else { int availableBlocksCount = 0; for (int i = 0; i < blockAvailable.Length; i++) { if (blockAvailable[i] == FILE_BLOCK_AVAILABLE) { availableBlocksCount++; } } FileStream fS; if (blockAvailable.Length == availableBlocksCount) { fS = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); } else { fS = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite); } sharedFile = new SharedFile(fS, metaData, blockAvailable, availableBlocksCount, syncCxt); _sharedFiles.Add(metaData.FileID, sharedFile); sharedFile._state = SharedFileState.Paused; if (state != SharedFileState.Paused) { sharedFile.Start(); } } } return(sharedFile); } }
private void OnBlockDownloaded(FileBlockDownloadManager downloadedBlock) { lock (_downloadingBlocks) { if (_downloadingBlocks.Remove(downloadedBlock)) { if (WriteBlock(downloadedBlock)) { //block downloaded //Debug.Write("SharedFile.BlockDownloaded", "block: " + downloadedBlock.BlockNumber); if (BlockDownloaded != null) { RaiseEventBlockDownloaded(); } } else { //block download fail/corrupt; add block again in pending list lock (_pendingBlocks) { _pendingBlocks.Add(downloadedBlock.BlockNumber); } } //start new block download FileBlockDownloadManager newDownload = GetRandomDownloadBlock(); if (newDownload != null) { _downloadingBlocks.Add(newDownload); } if (_downloadingBlocks.Count == 0) { //download COMPLETED! //set variables _isComplete = true; _state = SharedFileState.Sharing; _availableBlocksCount = _blockAvailable.Length; //stop download monitor _downloadMonitor.Dispose(); _downloadMonitor = null; //rename and open file again in read shared mode string filePath = _fileStream.Name; _fileStream.Close(); File.SetLastWriteTimeUtc(filePath, _metaData.LastModified); string newFilePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); File.Move(filePath, newFilePath); _fileStream = new FileStream(newFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); //remove seeders lock (_seeders) { _seeders.Clear(); } //announce advertisement for the complete file to all chats available with same file SendFileAdvertisement(); //notify event to UI //Debug.Write("SharedFile.BlockDownloaded", "COMPLETED!"); if (FileDownloaded != null) { RaiseEventFileDownloaded(); } } } } }
private void StartDownload() { if (_state != SharedFileState.Downloading) { _state = SharedFileState.Downloading; //get file if (_fileStream == null) { //find file name string filePath = Path.Combine(_profile.DownloadFolder, _metaData.FileName); int nameCount = 0; while (File.Exists(filePath)) { if (nameCount > 10000) { throw new BitChatException("Cannot download file as local file name not available."); } nameCount++; filePath = Path.Combine(_profile.DownloadFolder, Path.GetFileNameWithoutExtension(_metaData.FileName) + " [" + nameCount + "]" + Path.GetExtension(_metaData.FileName)); } //create file _fileStream = new FileStream(filePath + ".downloading", FileMode.Create, FileAccess.ReadWrite); //pre-allocate file _fileStream.SetLength(_metaData.FileSize); //init block available _blockAvailable = new FileBlockState[_blockAvailable.Length]; _availableBlocksCount = 0; } //list all pending blocks if (_pendingBlocks == null) { _pendingBlocks = new List <int>(_blockAvailable.Length); _rndPendingBlock = new Random(DateTime.UtcNow.Second); for (int i = 0; i < _blockAvailable.Length; i++) { if (_blockAvailable[i] != FileBlockState.Available) { _pendingBlocks.Add(i); } } } //announce file sharing participation in chats SendFileShareParticipate(); //start block download _downloadingBlocks = new List <FileBlockDownloadManager>(TOTAL_DOWNLOAD_BLOCKS); lock (_downloadingBlocks) { for (int i = 0; i < TOTAL_DOWNLOAD_BLOCKS; i++) { FileBlockDownloadManager download = GetRandomDownloadBlock(); if (download == null) { break; } _downloadingBlocks.Add(download); } } //start file transfer speed calculator _fileTransferSpeedCalculator = new Timer(FileTransferSpeedCalculatorAsync, null, 1000, 1000); //start download monitor _downloadMonitor = new Timer(DownloadMonitorAsync, null, DOWNLOAD_MONITOR_INTERVAL, Timeout.Infinite); if (FileDownloadStarted != null) { RaiseEventFileDownloadStarted(); } } }
private void StartDownload() { if (_state != SharedFileState.Downloading) { _state = SharedFileState.Downloading; //get file if (_fileStream == null) { //find file name string filePath = Path.Combine(_profile.DownloadFolder, _metaData.FileName); int nameCount = 0; while (File.Exists(filePath)) { if (nameCount > 10000) throw new BitChatException("Cannot download file as local file name not available."); nameCount++; filePath = Path.Combine(_profile.DownloadFolder, Path.GetFileNameWithoutExtension(_metaData.FileName) + " [" + nameCount + "]" + Path.GetExtension(_metaData.FileName)); } //create file _fileStream = new FileStream(filePath + ".downloading", FileMode.Create, FileAccess.ReadWrite); //pre-allocate file _fileStream.SetLength(_metaData.FileSize); //init block available _blockAvailable = new FileBlockState[_blockAvailable.Length]; _availableBlocksCount = 0; } //list all pending blocks if (_pendingBlocks == null) { _pendingBlocks = new List<int>(_blockAvailable.Length); _rndPendingBlock = new Random(DateTime.UtcNow.Second); for (int i = 0; i < _blockAvailable.Length; i++) { if (_blockAvailable[i] != FileBlockState.Available) _pendingBlocks.Add(i); } } //announce file sharing participation in chats SendFileShareParticipate(); //start block download _downloadingBlocks = new List<FileBlockDownloadManager>(TOTAL_DOWNLOAD_BLOCKS); lock (_downloadingBlocks) { for (int i = 0; i < TOTAL_DOWNLOAD_BLOCKS; i++) { FileBlockDownloadManager download = GetRandomDownloadBlock(); if (download == null) break; _downloadingBlocks.Add(download); } } //start file transfer speed calculator _fileTransferSpeedCalculator = new Timer(FileTransferSpeedCalculatorAsync, null, 1000, 1000); //start download monitor _downloadMonitor = new Timer(DownloadMonitorAsync, null, DOWNLOAD_MONITOR_INTERVAL, Timeout.Infinite); if (FileDownloadStarted != null) RaiseEventFileDownloadStarted(); } }
private void OnBlockDownloaded(FileBlockDownloadManager downloadedBlock) { lock (_downloadingBlocks) { if (_downloadingBlocks.Remove(downloadedBlock)) { if (WriteBlock(downloadedBlock)) { //block downloaded //Debug.Write("SharedFile.BlockDownloaded", "block: " + downloadedBlock.BlockNumber); if (BlockDownloaded != null) RaiseEventBlockDownloaded(); } else { //block download fail/corrupt; add block again in pending list lock (_pendingBlocks) { _pendingBlocks.Add(downloadedBlock.BlockNumber); } } //start new block download FileBlockDownloadManager newDownload = GetRandomDownloadBlock(); if (newDownload != null) _downloadingBlocks.Add(newDownload); if (_downloadingBlocks.Count == 0) { //download COMPLETED! //set variables _isComplete = true; _state = SharedFileState.Sharing; _availableBlocksCount = _blockAvailable.Length; //stop download monitor _downloadMonitor.Dispose(); _downloadMonitor = null; //rename and open file again in read shared mode string filePath = _fileStream.Name; _fileStream.Close(); File.SetLastWriteTimeUtc(filePath, _metaData.LastModified); string newFilePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); File.Move(filePath, newFilePath); _fileStream = new FileStream(newFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); //remove seeders lock (_seeders) { _seeders.Clear(); } //announce advertisement for the complete file to all chats available with same file SendFileAdvertisement(); //notify event to UI //Debug.Write("SharedFile.BlockDownloaded", "COMPLETED!"); if (FileDownloaded != null) RaiseEventFileDownloaded(); } } } }