예제 #1
0
        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);
            }
        }
예제 #2
0
        private SharedFile(FileStream fS, SharedFileMetaData metaData, byte[] blockAvailable, int availableBlocksCount, SynchronizationContext syncCxt)
        {
            _fileStream           = fS;
            _metaData             = metaData;
            _blockAvailable       = blockAvailable;
            _availableBlocksCount = availableBlocksCount;
            _syncCxt = syncCxt;

            _isComplete = (_blockAvailable.Length == _availableBlocksCount);
        }
예제 #3
0
        internal static SharedFile PrepareDownloadFile(SharedFileMetaData metaData, 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 byte[metaData.BlockHash.Length], 0, syncCxt);
                    _sharedFiles.Add(metaData.FileID, sharedFile);
                }

                return(sharedFile);
            }
        }
예제 #4
0
        internal static SharedFile ShareFile(string filePath, string hashAlgo, 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;
            {
                int totalBlocksPossible = BUFFER_SIZE / hashSize;
                blockSize = Convert.ToInt32(fS.Length / totalBlocksPossible);

                if (blockSize < FILE_BLOCK_MINIMUM_SIZE)
                {
                    blockSize = FILE_BLOCK_MINIMUM_SIZE;
                }
                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][];
            byte[]   blockAvailable = new byte[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] = FILE_BLOCK_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)
                    {
                        //close the file and do nothing
                        fS.Dispose();
                    }
                    else
                    {
                        //since the current shared file is incomplete and we are adding a complete shared file copy

                        //stop current download process
                        sharedFile.Pause();
                        sharedFile._fileStream.Dispose();

                        //update the current object with new file data
                        sharedFile._fileStream           = fS;
                        sharedFile._blockAvailable       = blockAvailable;
                        sharedFile._availableBlocksCount = blockAvailable.Length;
                        sharedFile._isComplete           = true;

                        //start sharing new file
                        sharedFile.StartSharing();
                    }
                }
                else
                {
                    sharedFile = new SharedFile(fS, metaData, blockAvailable, blockAvailable.Length, syncCxt);
                    sharedFile.StartSharing();

                    _sharedFiles.Add(metaData.FileID, sharedFile);
                }

                return(sharedFile);
            }
        }