Esempio n. 1
0
        public void Test_BufferStream()
        {
            //for (int i = 0; i < 10; i++)
            Parallel.For(0, 32, new ParallelOptions() { MaxDegreeOfParallelism = 64 }, i =>
            {
                //using (MemoryStream stream = new MemoryStream())
                using (BufferStream stream = new BufferStream(_bufferManager))
                {
                    byte[] buffer = _bufferManager.TakeBuffer(1024 * 1024); //new byte[_random.Next(128, 1024 * 1024 * 10)];
                    long seek = _random.Next(64, buffer.Length);
                    //long seek = 0;

                    _random.NextBytes(buffer);

                    stream.Write(buffer, 0, buffer.Length);
                    stream.Position = seek;

                    byte[] buff2 = _bufferManager.TakeBuffer(buffer.Length); //new byte[buffer.Length];
                    stream.Read(buff2, (int)seek, buff2.Length - (int)seek);

                    if (!CollectionUtilities.Equals(buffer, (int)seek, buff2, (int)seek, buffer.Length - (int)seek))
                    {
                        Assert.IsTrue(CollectionUtilities.Equals(buffer, (int)seek, buff2, (int)seek, buffer.Length - (int)seek));
                    }

                    _bufferManager.ReturnBuffer(buffer);
                    _bufferManager.ReturnBuffer(buff2);
                }
            });

            using (MemoryStream mstream = new MemoryStream())
            using (BufferStream stream = new BufferStream(_bufferManager))
            {
                for (int i = 0; i < 1024 * 1024; i++)
                {
                    var v = (byte)_random.Next(0, 255);
                    mstream.WriteByte(v);
                    stream.WriteByte(v);
                }

                mstream.Seek(0, SeekOrigin.Begin);
                stream.Seek(0, SeekOrigin.Begin);

                Assert.IsTrue(mstream.Length == stream.Length);

                for (int i = 0; i < 1024 * 1024; i++)
                {
                    Assert.IsTrue(mstream.ReadByte() == stream.ReadByte());
                }
            }
        }
        public override void Send(System.IO.Stream stream, TimeSpan timeout, Information options)
        {
            if (_disposed) throw new ObjectDisposedException(this.GetType().FullName);
            if (!_connect) throw new ConnectionException();
            if (stream == null) throw new ArgumentNullException(nameof(stream));
            if (stream.Length == 0) throw new ArgumentOutOfRangeException(nameof(stream));

            bool isCompress = true;

            if (options != null)
            {
                if (options.Contains("IsCompress")) isCompress = (bool)options["IsCompress"];
            }

            lock (_sendLock)
            {
                using (RangeStream targetStream = new RangeStream(stream, stream.Position, stream.Length - stream.Position, true))
                {
                    try
                    {
                        var list = new List<KeyValuePair<byte, Stream>>();

                        if (isCompress)
                        {
                            if (_otherCompressAlgorithm.HasFlag(CompressAlgorithm.Deflate))
                            {
                                BufferStream deflateBufferStream = null;

                                try
                                {
                                    deflateBufferStream = new BufferStream(_bufferManager);

                                    using (DeflateStream deflateStream = new DeflateStream(deflateBufferStream, CompressionMode.Compress, true))
                                    using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4))
                                    {
                                        int length;

                                        while ((length = targetStream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0)
                                        {
                                            deflateStream.Write(safeBuffer.Value, 0, length);
                                        }
                                    }

                                    deflateBufferStream.Seek(0, SeekOrigin.Begin);

                                    list.Add(new KeyValuePair<byte, Stream>((byte)1, deflateBufferStream));
                                }
                                catch (Exception e)
                                {
                                    if (deflateBufferStream != null)
                                    {
                                        deflateBufferStream.Dispose();
                                    }

                                    throw e;
                                }
                            }
                        }

                        list.Add(new KeyValuePair<byte, Stream>((byte)0, new WrapperStream(targetStream, true)));

                        list.Sort((x, y) =>
                        {
                            int c = x.Value.Length.CompareTo(y.Value.Length);
                            if (c != 0) return c;

                            return x.Key.CompareTo(y.Key);
                        });

            #if DEBUG
                        if (list[0].Value.Length != targetStream.Length)
                        {
                            Debug.WriteLine("Send : {0}→{1} {2}",
                                NetworkConverter.ToSizeString(targetStream.Length),
                                NetworkConverter.ToSizeString(list[0].Value.Length),
                                NetworkConverter.ToSizeString(list[0].Value.Length - targetStream.Length));
                        }
            #endif

                        for (int i = 1; i < list.Count; i++)
                        {
                            list[i].Value.Dispose();
                        }

                        var headerStream = new BufferStream(_bufferManager);
                        headerStream.WriteByte((byte)list[0].Key);

                        using (var dataStream = new UniteStream(headerStream, list[0].Value))
                        {
                            _connection.Send(dataStream, timeout, options);
                        }
                    }
                    catch (ConnectionException e)
                    {
                        throw e;
                    }
                    catch (Exception e)
                    {
                        throw new ConnectionException(e.Message, e);
                    }
                }
            }
        }
        private static Stream Compress(Stream stream)
        {
            if (stream == null) throw new ArgumentNullException("stream");

            var targetStream = new RangeStream(stream, true);

            List<KeyValuePair<byte, Stream>> list = new List<KeyValuePair<byte, Stream>>();

            try
            {
                targetStream.Seek(0, SeekOrigin.Begin);

                BufferStream deflateBufferStream = null;

                try
                {
                    deflateBufferStream = new BufferStream(_bufferManager);

                    using (DeflateStream deflateStream = new DeflateStream(deflateBufferStream, CompressionMode.Compress, true))
                    {
                        byte[] compressBuffer = null;

                        try
                        {
                            compressBuffer = _bufferManager.TakeBuffer(1024 * 4);

                            int i = -1;

                            while ((i = targetStream.Read(compressBuffer, 0, compressBuffer.Length)) > 0)
                            {
                                deflateStream.Write(compressBuffer, 0, i);
                            }
                        }
                        finally
                        {
                            if (compressBuffer != null)
                            {
                                _bufferManager.ReturnBuffer(compressBuffer);
                            }
                        }
                    }

                    deflateBufferStream.Seek(0, SeekOrigin.Begin);

                    list.Add(new KeyValuePair<byte, Stream>((byte)ConvertCompressionAlgorithm.Deflate, deflateBufferStream));
                }
                catch (Exception)
                {
                    if (deflateBufferStream != null)
                    {
                        deflateBufferStream.Dispose();
                    }
                }
            }
            catch (Exception)
            {

            }

            list.Add(new KeyValuePair<byte, Stream>((byte)ConvertCompressionAlgorithm.None, targetStream));

            list.Sort((x, y) =>
            {
                int c = x.Value.Length.CompareTo(y.Value.Length);
                if (c != 0) return c;

                return x.Key.CompareTo(y.Key);
            });

            #if DEBUG
            if (list[0].Value.Length != targetStream.Length)
            {
                Debug.WriteLine("ContentConverter Compress {3} : {0}→{1} {2}",
                    NetworkConverter.ToSizeString(targetStream.Length),
                    NetworkConverter.ToSizeString(list[0].Value.Length),
                    NetworkConverter.ToSizeString(list[0].Value.Length - targetStream.Length),
                    (ConvertCompressionAlgorithm)list[0].Key);
            }
            #endif

            for (int i = 1; i < list.Count; i++)
            {
                list[i].Value.Dispose();
            }

            BufferStream metadataStream = new BufferStream(_bufferManager);
            metadataStream.WriteByte((byte)list[0].Key);

            return new UniteStream(metadataStream, list[0].Value);
        }
        private static Stream Encrypt(Stream stream, IExchangeEncrypt publicKey)
        {
            if (stream == null) throw new ArgumentNullException("stream");
            if (publicKey == null) throw new ArgumentNullException("publicKey");

            try
            {
                BufferStream outStream = null;

                try
                {
                    outStream = new BufferStream(_bufferManager);
                    outStream.WriteByte((byte)ConvertCryptoAlgorithm.Aes256);

                    byte[] cryptoKey = new byte[32];
                    _random.GetBytes(cryptoKey);

                    {
                        var encryptedBuffer = Exchange.Encrypt(publicKey, cryptoKey);
                        outStream.Write(NetworkConverter.GetBytes((int)encryptedBuffer.Length), 0, 4);
                        outStream.Write(encryptedBuffer, 0, encryptedBuffer.Length);
                    }

                    byte[] iv = new byte[32];
                    _random.GetBytes(iv);
                    outStream.Write(iv, 0, iv.Length);

                    using (Stream inStream = new WrapperStream(stream, true))
                    {
                        using (var rijndael = new RijndaelManaged() { KeySize = 256, BlockSize = 256, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 })
                        using (CryptoStream cs = new CryptoStream(inStream, rijndael.CreateEncryptor(cryptoKey, iv), CryptoStreamMode.Read))
                        {
                            byte[] buffer = null;

                            try
                            {
                                buffer = _bufferManager.TakeBuffer(1024 * 4);

                                int i = -1;

                                while ((i = cs.Read(buffer, 0, buffer.Length)) > 0)
                                {
                                    outStream.Write(buffer, 0, i);
                                }
                            }
                            finally
                            {
                                if (buffer != null)
                                {
                                    _bufferManager.ReturnBuffer(buffer);
                                }
                            }
                        }
                    }

                    outStream.Seek(0, SeekOrigin.Begin);
                }
                catch (Exception)
                {
                    if (outStream != null)
                    {
                        outStream.Dispose();
                    }

                    throw;
                }

                return outStream;
            }
            catch (Exception e)
            {
                throw new ArgumentException(e.Message, e);
            }
        }
        private static Stream AddHash(Stream stream)
        {
            if (stream == null) throw new ArgumentNullException("stream");

            try
            {
                var targetStream = new RangeStream(stream, true);

                BufferStream metadataStream = new BufferStream(_bufferManager);
                metadataStream.WriteByte((byte)ConvertHashAlgorithm.Sha256);

                targetStream.Seek(0, SeekOrigin.Begin);
                var hash = Sha256.ComputeHash(targetStream);

                BufferStream hashStream = new BufferStream(_bufferManager);
                hashStream.Write(hash, 0, hash.Length);

                return new UniteStream(metadataStream, targetStream, hashStream);
            }
            catch (Exception e)
            {
                throw new ArgumentException(e.Message, e);
            }
        }