public SharedFileInfo(string filePath, SharedFileMetaData fileMetaData, FileBlockState[] blockAvailable, bool isPaused)
 {
     _filePath = filePath;
     _fileMetaData = fileMetaData;
     _blockAvailable = blockAvailable;
     _isPaused = isPaused;
 }
Exemple #2
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);
            }
        }
        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;
            }
        }
        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;
            }
        }