internal static SharedFile PrepareDownloadFile(SharedFileMetaData metaData, BitChat chat, BitChat.Peer seeder, BitChatProfile profile, SynchronizationContext syncCxt) { //check if file already exists lock (_sharedFiles) { SharedFile sharedFile; if (_sharedFiles.ContainsKey(metaData.FileID)) { sharedFile = _sharedFiles[metaData.FileID]; } else { sharedFile = new SharedFile(null, metaData, new FileBlockState[metaData.BlockHash.Length], 0, syncCxt); sharedFile._profile = profile; _sharedFiles.Add(metaData.FileID, sharedFile); } sharedFile.AddChat(chat); sharedFile.AddSeeder(seeder); return(sharedFile); } }
private SharedFile(FileStream fS, SharedFileMetaData metaData, FileBlockState[] blockAvailable, int availableBlocksCount, SynchronizationContext syncCxt) { _fileStream = fS; _metaData = metaData; _blockAvailable = blockAvailable; _availableBlocksCount = availableBlocksCount; _syncCxt = syncCxt; _isComplete = (_blockAvailable.Length == _availableBlocksCount); }
internal static SharedFile LoadFile(string filePath, SharedFileMetaData metaData, FileBlockState[] blockAvailable, bool isPaused, BitChat chat, SynchronizationContext syncCxt) { //check if file already shared lock (_sharedFiles) { SharedFile sharedFile; if (_sharedFiles.ContainsKey(metaData.FileID)) { sharedFile = _sharedFiles[metaData.FileID]; } else { int availableBlocksCount = 0; for (int i = 0; i < blockAvailable.Length; i++) { if (blockAvailable[i] == FileBlockState.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); sharedFile._state = SharedFileState.Paused; _sharedFiles.Add(metaData.FileID, sharedFile); if (!isPaused) { sharedFile.Start(); } } sharedFile.AddChat(chat); return(sharedFile); } }
internal static SharedFile ShareFile(string filePath, string hashAlgo, BitChat chat, SynchronizationContext syncCxt) { FileStream fS = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); HashAlgorithm hash = HashAlgorithm.Create(hashAlgo); int hashSize = hash.HashSize / 8; //calculate block size int blockSize; { //header size = ChatMessage header + FileAdvertisement header int packetHeaderSize = (20 + 1 + 2) + (1 + 1 + 255 + 1 + 255 + 8 + 8 + 4 + 1 + 10 + 1); int packetDataSize = 65536 - packetHeaderSize; int totalBlocksPossible = packetDataSize / hashSize; blockSize = Convert.ToInt32(fS.Length / totalBlocksPossible); if (blockSize <= short.MaxValue) { blockSize = short.MaxValue + 1; } else { //align to 16 bytes int remainder = blockSize % 16; if (remainder > 0) { blockSize = blockSize - remainder + 16; } } } //compute block hashes and file info hash int totalBlocks = Convert.ToInt32(Math.Ceiling(Convert.ToDouble((double)fS.Length / blockSize))); byte[][] blockHash = new byte[totalBlocks][]; FileBlockState[] blockAvailable = new FileBlockState[totalBlocks]; //init for (int i = 0; i < totalBlocks; i++) { long offset = i * blockSize; long length = blockSize; if ((offset + length) > fS.Length) { length = fS.Length - offset; } blockHash[i] = hash.ComputeHash(new OffsetStream(fS, offset, length)); blockAvailable[i] = FileBlockState.Available; } //get file meta data SharedFileMetaData metaData = new SharedFileMetaData(Path.GetFileName(fS.Name), WebUtilities.GetContentType(fS.Name), File.GetLastWriteTimeUtc(fS.Name), fS.Length, blockSize, hashAlgo, blockHash); //check if file already shared lock (_sharedFiles) { SharedFile sharedFile; if (_sharedFiles.ContainsKey(metaData.FileID)) { sharedFile = _sharedFiles[metaData.FileID]; if (sharedFile._isComplete) { fS.Dispose(); } else { sharedFile.Remove(chat); sharedFile = new SharedFile(fS, metaData, blockAvailable, blockAvailable.Length, syncCxt); sharedFile.StartSharing(); _sharedFiles.Add(metaData.FileID, sharedFile); } } else { sharedFile = new SharedFile(fS, metaData, blockAvailable, blockAvailable.Length, syncCxt); sharedFile.StartSharing(); _sharedFiles.Add(metaData.FileID, sharedFile); } sharedFile.AddChat(chat); return(sharedFile); } }