Пример #1
0
            public SharedFileInfo(BinaryReader bR)
            {
                if (Encoding.ASCII.GetString(bR.ReadBytes(2)) != "FI")
                {
                    throw new BitChatException("Invalid SharedFileInfo data format.");
                }

                byte version = bR.ReadByte();

                switch (version)
                {
                case 1:
                    _filePath     = Encoding.UTF8.GetString(bR.ReadBytes(bR.ReadByte()));
                    _fileMetaData = new SharedFileMetaData(bR);

                    _blockAvailable = new FileBlockState[bR.ReadInt32()];
                    for (int i = 0; i < _blockAvailable.Length; i++)
                    {
                        _blockAvailable[i] = (FileBlockState)bR.ReadByte();
                    }

                    _isPaused = bR.ReadBoolean();
                    break;

                default:
                    throw new BitChatException("SharedFileInfo data version not supported.");
                }
            }
Пример #2
0
 public SharedFileInfo(string filePath, SharedFileMetaData fileMetaData, byte[] blockAvailable, SharedFileState state)
 {
     _filePath       = filePath;
     _fileMetaData   = fileMetaData;
     _blockAvailable = blockAvailable;
     _state          = state;
 }
Пример #3
0
 public SharedFileInfo(string filePath, SharedFileMetaData fileMetaData, FileBlockState[] blockAvailable, bool isPaused)
 {
     _filePath       = filePath;
     _fileMetaData   = fileMetaData;
     _blockAvailable = blockAvailable;
     _isPaused       = isPaused;
 }
Пример #4
0
            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;
                    }
                }
            }
Пример #5
0
        public static byte[] CreateFileAdvertisement(SharedFileMetaData fileMetaData)
        {
            using (MemoryStream mS = new MemoryStream(64 * 1024))
            {
                mS.WriteByte((byte)BitChatMessageType.FileAdvertisement); //1 byte
                fileMetaData.WriteTo(mS);

                return(mS.ToArray());
            }
        }
        public MessageItem(string sender, SharedFileMetaData sharedFileMetaData)
        {
            _messageNumber = -1;

            _type        = MessageType.SharedFileMetaData;
            _messageDate = DateTime.UtcNow;
            _sender      = sender;

            _sharedFileMetaData = sharedFileMetaData;
        }
Пример #7
0
        public static byte[] CreateFileAdvertisement(SharedFileMetaData fileMetaData)
        {
            using (MemoryStream mS = new MemoryStream(64 * 1024))
            {
                mS.WriteByte((byte)BitChatMessageType.FileAdvertisement); //1 byte

                fileMetaData.WriteTo(mS);

                return mS.ToArray();
            }
        }
Пример #8
0
            public SharedFileInfo(BinaryReader bR)
            {
                if (Encoding.ASCII.GetString(bR.ReadBytes(2)) != "FI")
                    throw new BitChatException("Invalid SharedFileInfo data format.");

                byte version = bR.ReadByte();

                switch (version)
                {
                    case 1:
                        _filePath = Encoding.UTF8.GetString(bR.ReadBytes(bR.ReadByte()));
                        _fileMetaData = new SharedFileMetaData(bR);

                        _blockAvailable = new FileBlockState[bR.ReadInt32()];
                        for (int i = 0; i < _blockAvailable.Length; i++)
                            _blockAvailable[i] = (FileBlockState)bR.ReadByte();

                        _isPaused = bR.ReadBoolean();
                        break;

                    default:
                        throw new BitChatException("SharedFileInfo data version not supported.");
                }
            }
        public MessageItem(MessageStore store, int messageNumber)
        {
            _messageNumber = messageNumber;
            byte[] messageData = store.ReadMessage(messageNumber);

            using (MemoryStream mS = new MemoryStream(messageData))
            {
                if (Encoding.ASCII.GetString(messageData, 0, 2) == "MI")
                {
                    //new format
                    BincodingDecoder decoder = new BincodingDecoder(mS, "MI");

                    switch (decoder.Version)
                    {
                    case 1:
                        _type        = (MessageType)decoder.DecodeNext().GetByteValue();
                        _messageDate = decoder.DecodeNext().GetDateTimeValue();

                        switch (_type)
                        {
                        case MessageType.Info:
                            _message = decoder.DecodeNext().GetStringValue();
                            break;

                        case MessageType.TextMessage:
                        case MessageType.InvitationMessage:
                            _sender  = decoder.DecodeNext().GetStringValue();
                            _message = decoder.DecodeNext().GetStringValue();

                            {
                                List <Bincoding> rcptDataList = decoder.DecodeNext().GetList();

                                _recipients = new MessageRecipient[rcptDataList.Count];
                                int i = 0;

                                foreach (Bincoding data in rcptDataList)
                                {
                                    _recipients[i++] = new MessageRecipient(data.GetValueStream());
                                }
                            }
                            break;

                        case MessageType.SharedFileMetaData:
                            _sender             = decoder.DecodeNext().GetStringValue();
                            _sharedFileMetaData = new SharedFileMetaData(decoder.DecodeNext().GetValueStream());
                            break;
                        }

                        break;

                    default:
                        throw new InvalidDataException("Cannot decode data format: version not supported.");
                    }
                }
                else
                {
                    //old format support
                    BincodingDecoder decoder = new BincodingDecoder(mS);

                    _type        = (MessageType)decoder.DecodeNext().GetByteValue();
                    _messageDate = _epoch.AddSeconds(decoder.DecodeNext().GetLongValue());

                    switch (_type)
                    {
                    case MessageType.Info:
                        _message = decoder.DecodeNext().GetStringValue();
                        break;

                    case MessageType.TextMessage:
                        _sender     = decoder.DecodeNext().GetStringValue();
                        _message    = decoder.DecodeNext().GetStringValue();
                        _recipients = new MessageRecipient[] { };
                        break;
                    }
                }
            }
        }
Пример #10
0
 public SharedFileInfo(string filePath, SharedFileMetaData fileMetaData, FileBlockState[] blockAvailable, bool isPaused)
 {
     _filePath = filePath;
     _fileMetaData = fileMetaData;
     _blockAvailable = blockAvailable;
     _isPaused = isPaused;
 }
Пример #11
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);
        }
Пример #12
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;
            }
        }
Пример #13
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;
            }
        }
Пример #14
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;
            }
        }