示例#1
0
        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);
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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);
            }
        }
示例#4
0
        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);
            }
        }