Example #1
0
        public async Task Test(object value, Func <AsyncBinaryWriter, object, Task> awriteFunc, Action <BinaryWriter, object> swriteFunc, Func <BinaryReader, object> readFunc, Encoding encoding = null)
        {
            encoding = encoding ?? Encoding.UTF8;

            var sstream = new MemoryStream();
            var swriter = new BinaryWriter(sstream, encoding);

            swriteFunc(swriter, value);
            swriter.Flush();
            sstream.Position = 0;

            var astream = new MemoryStream();
            var awriter = new AsyncBinaryWriter(astream, encoding);

            await awriteFunc(awriter, value);

            await awriter.FlushAsync();

            astream.Position = 0;

            // The following 2 assertions seem redundant. That's okay, though.

            // did AsyncBinaryWriter and BinaryWriter produce same bytes?
            Assert.Equal(sstream.ToArray(), astream.ToArray());

            // did AsyncBinaryWriter produce bytes that can be read by BinaryReader?
            var reader = new BinaryReader(astream, encoding);
            var result = readFunc(reader);

            Assert.Equal(value, result);
        }
Example #2
0
        private async Task WriteUnifiedFrameContent(
            AsyncBinaryWriter writer,
            int streamId,
            UnifiedFrameContent unifiedFrameContent)
        {
            if (this.logger.IsEnabled(LogLevel.Debug))
            {
                using var memoryStream = new MemoryStream();
                using var memoryWriter = new AsyncBinaryWriter(memoryStream, Encoding.ASCII, false);

                await WriteFrame(memoryWriter, 2, 0, streamId, unifiedFrameContent.ToByteArray())
                .ConfigureAwait(false);

                byte[] sendingBytes = memoryStream.ToArray();

                this.logger.LogDebug(
                    "Sending to {0} with streamId={1}:" + Environment.NewLine + "{2}",
                    unifiedFrameContent.Header.Path,
                    streamId,
                    HexUtils.Dump(new ReadOnlyMemory <byte>(sendingBytes)));
                await writer.WriteAsync(sendingBytes).ConfigureAwait(false);
            }
            else
            {
                await WriteFrame(writer, 2, 0, streamId, unifiedFrameContent.ToByteArray())
                .ConfigureAwait(false);
            }
        }
 public async Task When_writing_an_Int32()
 {
     var ms = new MemoryStream();
     var sut = new AsyncBinaryWriter(ms);
     await sut.WriteAsync(100, CancellationToken.None);
     Assert.Equal(new byte[] { 100, 0, 0, 0 }, ms.ToArray());
 }
Example #4
0
        private static async Task WriteFrame(
            AsyncBinaryWriter writer,
            byte type,
            byte seqNum,
            int streamId,
            byte[] contents)
        {
            uint contentChecksum = 0;

            // TODO(zhangshuai.ustc): Support other platform
            if (Environment.OSVersion.Platform == PlatformID.Win32NT ||
                Environment.OSVersion.Platform == PlatformID.Win32Windows)
            {
                contentChecksum = Crc32C.Crc32CAlgorithm.Compute(contents);
            }

            var frameHeader = new FrameHeader(
                version: 1,
                type: type,
                sequenceNumber: seqNum,
                streamId: (uint)streamId,
                contentOffset: 20,
                contentLength: (ushort)contents.Length,
                contentChecksum: contentChecksum);
            await frameHeader.WriteTo(writer).ConfigureAwait(false);

            await writer.WriteAsync(contents).ConfigureAwait(false);
        }
Example #5
0
        public static async Task <AsyncBinaryWriter> WriteHeaderAsync(Stream stream, byte[] messageHeader, Ack ack)
        {
            /*
             * UInt16 Message Header Length
             * byte[] Message Header
             * UInt32 Version
             * UInt64 Ack
             * UInt32 Empty
             * UInt32 Content Length
             * byte[] Content
             */

            uint version = 0;

            var asyncBinaryWriter   = new AsyncBinaryWriter(stream);
            var messageHeaderLength = (ushort)messageHeader.Length;
            await asyncBinaryWriter.WriteAsync(messageHeaderLength);

            await stream.WriteAsync(messageHeader);

            await asyncBinaryWriter.WriteAsync(version);

            await asyncBinaryWriter.WriteAsync(ack.Value);

            // Empty
            await asyncBinaryWriter.WriteAsync(uint.MinValue);

            return(asyncBinaryWriter);
        }
Example #6
0
        public async Task The_WriteAsync_Method_Throws_When_Data_Is_Null()
        {
            var writer = new AsyncBinaryWriter(new MemoryStream());

            await Assert.ThrowsAsync <ArgumentNullException>(async() =>
            {
                await writer.WriteAsync(null);
            });
        }
 public async Task TestWriterCancellation(Func <AsyncBinaryWriter, CancellationToken, Task> f)
 {
     using (var cts = new CancellationTokenSource())
     {
         var ct     = cts.Token;
         var writer = new AsyncBinaryWriter(new SlowStream());
         cts.Cancel();
         await Assert.ThrowsAsync <TaskCanceledException>(() => f(writer, ct));
     }
 }
Example #8
0
        /// <summary>
        /// This takes an input file and encrypts it into the output file
        /// </summary>
        /// <param name="outStream"></param>
        /// <param name="password">the password for use as the key</param>
        /// <param name="fileStream"></param>
        public static async Task EncryptFileAsync(Stream fileStream, Stream outStream, string password)
        {
            long lSize = fileStream.Length;       // the size of the input file for storing

            byte[] bytes = new byte[BUFFER_SIZE]; // the buffer
            int    read  = -1;                    // the amount of bytes read from the input file
            int    value = 0;                     // the amount overall read from the input file for progress

            // generate IV and Salt
            byte[] IV   = GenerateRandomBytes(16);
            byte[] salt = GenerateRandomBytes(16);

            // create the crypting object
            SymmetricAlgorithm sma = CryptoHelper.CreateRijndael(password, salt);

            sma.IV = IV;

            // write the IV and salt to the beginning of the file
            await outStream.WriteAsync(IV, 0, IV.Length);

            await outStream.WriteAsync(salt, 0, salt.Length);

            // create the hashing and crypto streams
            HashAlgorithm hasher = SHA256.Create();

            await using var cout = new CryptoStream(outStream, sma.CreateEncryptor(), CryptoStreamMode.Write);
            await using (var chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write))
            {
                // write the size of the file to the output file
                var bw = new AsyncBinaryWriter(cout);
                await bw.WriteAsync(lSize);

                // write the file cryptor tag to the file
                await bw.WriteAsync(FC_TAG);

                // read and the write the bytes to the crypto stream in BUFFER_SIZEd chunks
                while ((read = await fileStream.ReadAsync(bytes, 0, bytes.Length)) != 0)
                {
                    await cout.WriteAsync(bytes, 0, read);

                    await chash.WriteAsync(bytes, 0, read);

                    value += read;
                }

                // flush and close the hashing object
            }

            // read the hash
            byte[] hash = hasher.Hash;

            // write the hash to the end of the file
            await cout.WriteAsync(hash, 0, hash.Length);
        }
Example #9
0
        async Task <TResponse> AsyncCallAsync <TRequest, TResponse>(
            Method <TRequest, TResponse> method, TRequest request)
        {
            await pipeLock.WaitAsync();

            PipePair pipePair;

            availablePipePairs.TryTake(out pipePair);
            Debug.Assert(pipePair != null);
            try
            {
                var writer = new AsyncBinaryWriter(pipePair.OutPipe);
                var reader = new AsyncBinaryReader(pipePair.InPipe);

                // Send the RPC name.
                await writer.WriteAsync(method.FullName.Length);

                await writer.WriteAsync(Encoding.ASCII.GetBytes(method.FullName));

                // Send the request.
                using (var serializationContext = new SimpleSerializationContext())
                {
                    method.RequestMarshaller.ContextualSerializer(request, serializationContext);
                    byte[] requestBytes = serializationContext.GetPayload();
                    await writer.WriteAsync(requestBytes.Length);

                    await writer.WriteAsync(requestBytes);
                }

                // Read the response.
                int size = await reader.ReadInt32Async();

                byte[] responseBytes = await reader.ReadBytesAsync(size);

                var deserializationContext = new SimpleDeserializationContext(responseBytes);
                return(method.ResponseMarshaller.ContextualDeserializer(deserializationContext));
            }
            // Unfortunately, RpcExceptions can't be nested with InnerException.
            catch (EndOfStreamException e)
            {
                throw new RpcException(new Status(StatusCode.Unknown, e.ToString()),
                                       "Connection to server lost. Did it shut down?");
            }
            catch (Exception e) when(!(e is RpcException))
            {
                throw new RpcException(new Status(StatusCode.Unknown, e.ToString()),
                                       "Unknown failure: " + e);
            }
            finally
            {
                availablePipePairs.Add(pipePair);
                pipeLock.Release();
            }
        }
Example #10
0
        public async Task The_WriteAsync_Method_Works()
        {
            var stream   = new MemoryStream();
            var writer   = new AsyncBinaryWriter(stream);
            var expected = Encoding.UTF8.GetBytes("123456");

            await writer.WriteAsync(expected);

            var actual = stream.ToArray();

            Assert.Equal(expected, actual);
        }
Example #11
0
        public async Task The_WriteValueAsync_Method_Paddes_With_Zeroes()
        {
            var expected = Encoding.UTF8.GetBytes("123456");

            Array.Resize(ref expected, 12);
            var stream = new MemoryStream();
            var writer = new AsyncBinaryWriter(stream);

            var value = new StringPalmValue(expected.Length, Encoding.UTF8, true);
            await value.WriteValueAsync(writer, "123456");

            var actual = stream.ToArray();

            Assert.Equal(expected, actual);
        }
Example #12
0
        private static async Task <TcpClient> StartPlcAsync(ILogger logger, string hostname, int port)
        {
            var fakePlc = new TcpClient(hostname, port);

            logger.LogInformation("Fake PLC connected.");

            NetworkStream networkStream = fakePlc.GetStream();

            using var reader = new AsyncBinaryReader(networkStream, Encoding.ASCII, true);
            using var writer = new AsyncBinaryWriter(networkStream, Encoding.ASCII, true);

            logger.LogDebug("Receiving TestRequest frame...");
            byte[] receivedBytes = await reader.ReadBytesAsync(0x53).ConfigureAwait(false);

            logger.LogInformation("Received {0} bytes.", 0x53);

            byte[] sendingPayload = new UnifiedFrameContent
            {
                Header = new Header {
                    Status = 0
                },
                Payload = new TestResponse
                {
                    A = 42,
                    B = 3.1415926F,
                    C = "Hello World!",
                    D = Timestamp.FromDateTimeOffset(DateTimeOffset.Parse("2019-10-29T21:42:13.00000+8:00", CultureInfo.InvariantCulture)),
                }.ToByteString(),
            }.ToByteArray();
            var sendingHeader = new FrameHeader(
                version: 1,
                type: 2,
                sequenceNumber: 0,
                streamId: 1,
                contentOffset: 20,
                contentLength: (ushort)sendingPayload.Length,
                contentChecksum: Crc32C.Crc32CAlgorithm.Compute(sendingPayload));

            logger.LogDebug("Sending TestResponse frame header...");
            await sendingHeader.WriteTo(writer).ConfigureAwait(false);

            logger.LogDebug("Sending TestResponse frame body...");
            await writer.WriteAsync(sendingPayload).ConfigureAwait(false);

            logger.LogInformation("Sent TestResponse.");

            return(fakePlc);
        }
Example #13
0
        public void Connect(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            stream.ReadTimeout  = RECEIVE_TIMEOUT;         // set read timeout to (15s default)
            stream.WriteTimeout = SEND_TIMEOUT;            // set write timeout to (15s default)

            // Most of the RFB protocol uses Big-Endian byte order, while
            // .NET uses Little-Endian. These wrappers convert between the
            // two.  See BigEndianReader and BigEndianWriter below for more details.
            Reader     = new BigEndianBinaryReader(stream);
            writer     = new BigEndianBinaryWriter(stream);
            ZrleReader = new ZRLECompressedReader(stream);
        }
Example #14
0
        public IntegrityTestFixture()
        {
            // create the server
            var server = new WsServer();

            server.StartAsync(new IPEndPoint(IPAddress.Loopback, 0), async stream =>
            {
                Server = stream;
            }).GetAwaiter().GetResult();

            // start client
            var client = new WsClient();

            Client = client.ConnectAsync(new Uri("ws://" + server.ListeningAddresses[0].Substring(7))).GetAwaiter().GetResult();
            Thread.Sleep(1000);
            Reader = new AsyncBinaryReader(Client);
            Writer = new AsyncBinaryWriter(Server);
        }
Example #15
0
 private async void BackgroundSendingTaskEntryPoint()
 {
     try
     {
         using var binaryWriter = new AsyncBinaryWriter(this.client.GetStream(), Encoding.ASCII, true);
         while (await this.requestQueue
                .OutputAvailableAsync()
                .ConfigureAwait(false))
         {
             await this.DrainSendingRequestContexts(binaryWriter).ConfigureAwait(false);
         }
     }
     catch (IOException e)
     {
         this.logger.LogError(e, "Error when receiving data from {0}", this.client.Client.RemoteEndPoint);
         this.client.Close();
         this.ConnectionClosed?.Invoke(this, new EventArgs());
     }
 }
Example #16
0
        public async Task ValidateReadWriteStatistics()
        {
            InterceptData clientData = null, serverData = null;
            var           server = new WsServer();
            await server.StartAsync(new IPEndPoint(IPAddress.Loopback, 0), async stream =>
            {
                await stream.WrapSocketAsync(x =>
                                             Task.FromResult <WStreamSocket>(new Interceptor(x, out serverData))
                                             );
                var abr = new AsyncBinaryReader(stream);
                for (int i = 0; i < 100000; i++)
                {
                    Assert.Equal(i, await abr.ReadInt32Async());
                }
                await stream.CloseAsync();
            });

            var client     = new WsClient();
            var connection = await client.ConnectAsync(new Uri("ws://" + server.ListeningAddresses[0].Substring(7)));

            await connection.WrapSocketAsync(x =>
                                             Task.FromResult <WStreamSocket>(new Interceptor(x, out clientData))
                                             );

            var abw = new AsyncBinaryWriter(connection);

            for (int i = 0; i < 100000; i++)
            {
                await abw.WriteAsync(i);
            }

            await abw.FlushAsync();

            await Task.Delay(1000);

            Assert.Equal(4 * 100000, clientData.BytesWritten);
            Assert.Equal(4 * 100000, serverData.BytesRead);

            client.Dispose();
            server.Dispose();
        }
Example #17
0
        public static async Task <AsyncBinaryWriter> WriteHeaderAsync(Stream stream, byte[] messageHeader, Ack ack,
                                                                      IpcMessageCommandType ipcMessageCommandType)
        {
            /*
             * UInt16 Message Header Length 消息头的长度
             * byte[] Message Header        消息头的内容
             * UInt32 Version        当前IPC服务的版本
             * UInt64 Ack            用于给对方确认收到消息使用
             * UInt32 Empty          给以后版本使用的值
             * UInt16 Command Type   命令类型,业务端的值将会是 0 而框架层采用其他值
             * UInt32 Content Length 这条消息的内容长度
             * byte[] Content        实际的内容
             */

            // 当前版本默认是 1 版本,这个值用来后续如果有协议上的更改时,兼容旧版本使用
            // - 版本是 0 的版本,每条消息都有回复 ack 的值
            const uint version = 1;

            var asyncBinaryWriter   = new AsyncBinaryWriter(stream);
            var messageHeaderLength = (ushort)messageHeader.Length;
            await asyncBinaryWriter.WriteAsync(messageHeaderLength);

            await stream.WriteAsync(messageHeader);

            // UInt32 Version
            await asyncBinaryWriter.WriteAsync(version);

            // UInt64 Ack
            await asyncBinaryWriter.WriteAsync(ack.Value);

            // UInt32 Empty
            await asyncBinaryWriter.WriteAsync(uint.MinValue);

            // UInt16 Command Type   命令类型,业务端的值将会是 0 而框架层采用其他值
            ushort commandType = (ushort)ipcMessageCommandType;
            await asyncBinaryWriter.WriteAsync(commandType);

            return(asyncBinaryWriter);
        }
Example #18
0
        public async Task WriteTo(AsyncBinaryWriter binaryWriter)
        {
            // Write magic signature.
            await binaryWriter.WriteAsync((byte)'D').ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)'R').ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)'Y').ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)0).ConfigureAwait(false);

            // Write version, type, sequence number.
            await binaryWriter.WriteAsync((byte)this.Version).ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)this.Type).ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)this.SequenceNumber).ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)0).ConfigureAwait(false);

            // Write stream id.
            await binaryWriter
            .WriteAsync(BinaryPrimitives.ReverseEndianness((uint)this.StreamId))
            .ConfigureAwait(false);

            // Write content offset & size.
            await binaryWriter
            .WriteAsync(BinaryPrimitives.ReverseEndianness((ushort)this.ContentOffset))
            .ConfigureAwait(false);

            await binaryWriter
            .WriteAsync(BinaryPrimitives.ReverseEndianness((ushort)this.ContentLength))
            .ConfigureAwait(false);

            // Write content checksum.
            await binaryWriter
            .WriteAsync(BinaryPrimitives.ReverseEndianness((uint)this.ContentChecksum))
            .ConfigureAwait(false);
        }
Example #19
0
        private async Task DrainSendingRequestContexts(AsyncBinaryWriter binaryWriter)
        {
            while (this.requestQueue.TryReceive(out RequestContext requestContext))
            {
                if (requestContext.CancellationToken.IsCancellationRequested ||
                    DateTime.Now > requestContext.Deadline)
                {
                    requestContext.TaskCompletionSource.SetResult(new UnifiedFrameContent
                    {
                        Header = new Header
                        {
                            Status        = (int)StatusCode.DeadlineExceeded,
                            StatusMessage = Status.DefaultCancelled.Detail,
                        },
                    });
                }

                var unifiedFrameContent = new UnifiedFrameContent()
                {
                    Header = new Header()
                    {
                        Path = requestContext.Path,
                    },
                    Payload = requestContext.Message.ToByteString(),
                };
                int streamId = Interlocked.Increment(ref this.counter);
                await this.WriteUnifiedFrameContent(binaryWriter, streamId, unifiedFrameContent)
                .ConfigureAwait(false);

                if (!this.receivingContexts.TryAdd(streamId, requestContext))
                {
                    throw new InvalidOperationException("Impossible");
                }

                this.logger.LogDebug("Request recorded as streamId={0}: {1}", streamId, requestContext.Message);
            }
        }
Example #20
0
        public async Task When_writing_a_structure()
        {
            var ms = new MemoryStream();
            var sut = new AsyncBinaryWriter(ms);

            await sut.WriteStructureAsync(new Symblr.Symbols.Pdb70.Pdb70Header()
            {
                PageSize = 0,
                BitmapPage = 1,
                PageCount = 2,
                IndexBytes = 3,
                Reserved = 4,
                IndexPage = 5
            }, CancellationToken.None);

            Assert.Equal(new byte[] { 
                0, 0, 0, 0, 
                1, 0, 0, 0, 
                2, 0, 0, 0, 
                3, 0, 0, 0, 
                4, 0, 0, 0, 
                5, 0, 0, 0,
            }, ms.ToArray());
        }
Example #21
0
        /// <summary>
        /// Writes the specified <paramref name="database"/> into the specified <paramref name="stream"/>.
        /// </summary>
        /// <param name="database">The palm database.</param>
        /// <param name="stream">The stream to write the database to.</param>
        public static async Task WriteAsync(PalmDatabase database, Stream stream)
        {
            Guard.NotNull(stream, nameof(stream));
            Guard.Not(stream.CanSeek == false, nameof(stream.CanSeek));
            Guard.Not(stream.CanWrite == false, nameof(stream.CanWrite));

            var writer = new AsyncBinaryWriter(stream);

            var nameValue = new StringPalmValue(32, Encoding.UTF8, zeroTerminated: true);
            await nameValue.WriteValueAsync(writer, database.Name);

            var attributesValue = new EnumPalmValue <PalmDatabaseAttributes>(2);
            await attributesValue.WriteValueAsync(writer, database.Attributes);

            var versionValue = new UIntPalmValue(2);
            await versionValue.WriteValueAsync(writer, (uint)database.Version);

            var creationDateValue = new DateTimeOffsetPalmValue();
            await creationDateValue.WriteValueAsync(writer, database.CreationDate);

            var modificationDateValue = new DateTimeOffsetPalmValue();
            await modificationDateValue.WriteValueAsync(writer, database.ModificationDate);

            var lastBackupDateValue = new DateTimeOffsetPalmValue();
            await lastBackupDateValue.WriteValueAsync(writer, database.LastBackupDate);

            var modificationNumberValue = new UIntPalmValue(4);
            await modificationNumberValue.WriteValueAsync(writer, database.ModificationNumber);

            var appInfoIdValue    = new UIntPalmValue(4);
            var offsetOfAppInfoId = writer.Stream.Position;
            await appInfoIdValue.WriteValueAsync(writer, 0);

            var sortInfoIdValue    = new UIntPalmValue(4);
            var offsetOfSortInfoId = writer.Stream.Position;
            await sortInfoIdValue.WriteValueAsync(writer, 0);

            var typeValue = new StringPalmValue(4, Encoding.UTF8, zeroTerminated: false);
            await typeValue.WriteValueAsync(writer, database.Type);

            var creatorValue = new StringPalmValue(4, Encoding.UTF8, zeroTerminated: false);
            await creatorValue.WriteValueAsync(writer, database.Creator);

            var uniqueIdSeedValue = new UIntPalmValue(4);
            await uniqueIdSeedValue.WriteValueAsync(writer, database.UniqueIdSeed);

            var nextRecordListIdValue = new UIntPalmValue(4);
            await nextRecordListIdValue.WriteValueAsync(writer, database.NextRecordListId);

            var numberOfRecordsValue = new UIntPalmValue(2);
            await numberOfRecordsValue.WriteValueAsync(writer, (uint)database.Records.Count);

            var recordUniqueIdsAndOffsetOfDataOffsets = new Dictionary <uint, long>();

            //Write the records
            uint uniqueId = 0;

            foreach (var record in database.Records)
            {
                recordUniqueIdsAndOffsetOfDataOffsets.Add(uniqueId, stream.Position);

                var recordDataOffsetValue = new UIntPalmValue(4);
                await recordDataOffsetValue.WriteValueAsync(writer, 0);

                var recordAttributeValue = new ByteArrayPalmValue(1);
                await recordAttributeValue.WriteValueAsync(writer, new[] { record.Attributes });

                var uniqueIdValue = new UIntPalmValue(3);
                await uniqueIdValue.WriteValueAsync(writer, uniqueId);

                record.UniqueId = uniqueId;

                uniqueId++;
            }

            var fillerValue = new ByteArrayPalmValue(2);
            await fillerValue.WriteValueAsync(writer, new byte[2]);

            //Write appInfo
            if (database.AppInfo.Any())
            {
                var appInfoId = (uint)writer.Stream.Position;

                var dataValue = new ByteArrayPalmValue(database.AppInfo.Length);
                await dataValue.WriteValueAsync(writer, database.AppInfo);

                var previousOffset = writer.Stream.Position;

                writer.Stream.Seek(offsetOfAppInfoId, SeekOrigin.Begin);

                await appInfoIdValue.WriteValueAsync(writer, appInfoId);

                writer.Stream.Seek(previousOffset, SeekOrigin.Begin);
            }

            //Write sortInfo
            if (database.SortInfo.Any())
            {
                var sortInfoId = (uint)writer.Stream.Position;

                var dataValue = new ByteArrayPalmValue(database.SortInfo.Length);
                await dataValue.WriteValueAsync(writer, database.SortInfo);

                var previousOffset = writer.Stream.Position;

                writer.Stream.Seek(offsetOfSortInfoId, SeekOrigin.Begin);

                await sortInfoIdValue.WriteValueAsync(writer, sortInfoId);

                writer.Stream.Seek(previousOffset, SeekOrigin.Begin);
            }

            //Write the record content
            foreach (var record in database.Records)
            {
                var offsetOfDataOffset = recordUniqueIdsAndOffsetOfDataOffsets[record.UniqueId];
                var dataOffset         = (uint)writer.Stream.Position;

                var dataValue = new ByteArrayPalmValue(record.Data.Length);
                await dataValue.WriteValueAsync(writer, record.Data);

                var endOffset = writer.Stream.Position;

                writer.Stream.Seek(offsetOfDataOffset, SeekOrigin.Begin);

                var recordDataOffsetValue = new UIntPalmValue(4);
                await recordDataOffsetValue.WriteValueAsync(writer, dataOffset);

                writer.Stream.Seek(endOffset, SeekOrigin.Begin);
            }
        }
        public async Task TestAsyncBinaryWriter()
        {
            byte customByte = 39;
            bool customBool = Unsafe.As <byte, bool>(ref customByte);

            object[] expectedResults =
            {
                true,
                false,
                customBool,
                (byte)42,
                (sbyte)-28,
                (short)-279,
                (ushort)64221,
                (int)-288888,
                (uint)3310229011,
                (float)3811.55f,
                (long)-19195205991011,
                (ulong)11223372036854775807,
                (double)Math.PI,
                (decimal)295222.2811m
            };

            using (var ms = new MemoryStream())
            {
                using (var wr = new AsyncBinaryWriter(ms, Encoding.Default, leaveOpen: true))
                {
                    foreach (dynamic obj in expectedResults)
                    {
                        await wr.WriteAsync(obj).ConfigureAwait(false);
                    }
                }

                ms.Position = 0;

                using (var rd = new BinaryReader(ms, Encoding.Default, leaveOpen: true))
                {
                    foreach (var obj in expectedResults)
                    {
                        switch (obj)
                        {
                        case bool b8:
                            ////Assert.Equal(b8, rd.ReadBoolean());
                            if (b8)
                            {
                                Assert.True(rd.ReadBoolean());
                            }
                            else
                            {
                                Assert.False(rd.ReadBoolean());
                            }

                            break;

                        case byte u8:
                            Assert.Equal(u8, rd.ReadByte());
                            break;

                        case sbyte s8:
                            Assert.Equal(s8, rd.ReadSByte());
                            break;

                        case short s16:
                            Assert.Equal(s16, rd.ReadInt16());
                            break;

                        case ushort u16:
                            Assert.Equal(u16, rd.ReadUInt16());
                            break;

                        case int s32:
                            Assert.Equal(s32, rd.ReadInt32());
                            break;

                        case uint u32:
                            Assert.Equal(u32, rd.ReadUInt32());
                            break;

                        case long s64:
                            Assert.Equal(s64, rd.ReadInt64());
                            break;

                        case ulong u64:
                            Assert.Equal(u64, rd.ReadUInt64());
                            break;

                        case float f32:
                            Assert.Equal(f32, rd.ReadSingle());
                            break;

                        case double f64:
                            Assert.Equal(f64, rd.ReadDouble());
                            break;

                        case decimal d128:
                            Assert.Equal(d128, rd.ReadDecimal());
                            break;
                        }
                    }
                }
            }
        }
        private static async Task CompressFileAsL33TZipAsync(
            Stream inputStream,
            Stream outputStream,
            IProgress <double> progress = null,
            CancellationToken ct        = default)
        {
            //
            var fileLength = inputStream.Length;

            //Write L33T Header
            using (var writer = new AsyncBinaryWriter(inputStream))
            {
                //Write L33T Header & File Length
                if (fileLength > int.MaxValue)
                {
                    await writer.WriteAsync(L66THeader.ToCharArray(), ct);

                    await writer.WriteAsync(fileLength, ct);
                }
                else
                {
                    await writer.WriteAsync(L33THeader.ToCharArray(), ct);

                    await writer.WriteAsync(Convert.ToInt32(fileLength), ct);
                }

                //Write Deflate specification (2 Byte)
                await writer.WriteAsync(new byte[] { 0x78, 0x9C }, ct);
            }

            //Write Content
            var buffer         = new byte[BufferSize];
            var totalBytesRead = 0L;
            var lastProgress   = 0d;
            int bytesRead;

            using var compressedStream = new DeflateStream(outputStream, CompressionLevel.Optimal);
            while ((bytesRead = await inputStream.ReadAsync(buffer, 0, buffer.Length, ct)) > 0)
            {
                ct.ThrowIfCancellationRequested();

                if (bytesRead > fileLength)
                {
                    totalBytesRead += fileLength;
                    await compressedStream.WriteAsync(buffer, 0, Convert.ToInt32(fileLength), ct);
                }
                else if (totalBytesRead + bytesRead <= fileLength)
                {
                    totalBytesRead += bytesRead;
                    await compressedStream.WriteAsync(buffer, 0, bytesRead, ct);
                }
                else if (totalBytesRead + bytesRead > fileLength)
                {
                    var leftToRead = fileLength - totalBytesRead;
                    totalBytesRead += leftToRead;
                    await compressedStream.WriteAsync(buffer, 0, Convert.ToInt32(leftToRead), ct);
                }

                var newProgress = (double)totalBytesRead / fileLength * 100;

                if (newProgress - lastProgress > 1)
                {
                    progress?.Report(newProgress);
                    lastProgress = newProgress;
                }

                if (totalBytesRead >= fileLength)
                {
                    break;
                }
            }
        }
Example #24
0
 /// <summary>
 /// Asynchronously writes the bit set to the specified writer.
 /// </summary>
 /// <param name="writer">The writer.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>
 /// A <see cref="Task"/> that represents the asynchronous write operation.
 /// </returns>
 public async Task WriteAsync(AsyncBinaryWriter writer, CancellationToken cancellationToken)
 {
     await writer.WriteAsync(Words.Length, cancellationToken);
     var bytes = new byte[Words.Length * sizeof(int)];
     Buffer.BlockCopy(Words, 0, bytes, 0, bytes.Length);
     await writer.BaseStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
 }
Example #25
0
        /// <summary>
        /// Securely exchanges a secret key
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="ecParams">ECDSA public / private keypair used for signing</param>
        /// <returns>A tuple containing a 256 bit hashed secret key, and the fingerprint of the remote</returns>
        /// <exception cref="CryptographicException"></exception>
        /// <exception cref="InvalidDataException">Thrown when the remote sends invalid data</exception>
        public static async Task <(byte[], ECPoint)> ExchangeKeyAsync(this WsStream stream, ECParameters ecParams)
        {
            if (ecParams.D is null)
            {
                throw new CryptographicException("Private key must be provided");
            }
            ECDsa ecDsa = ECDsa.Create(ecParams);
            // TODO: Harden security (prevent abuse, double check everything)
            // host authentication
            var pubBytes = ecDsa.ExportSubjectPublicKeyInfo();

            // key exchange
            var ecdh       = ECDiffieHellman.Create();
            var kePubBytes = ecdh.ExportSubjectPublicKeyInfo();

            // sign ecdh key to authenticate
            var signed = ecDsa.SignData(kePubBytes, HashAlgorithmName.SHA256);

            var bw = new AsyncBinaryWriter(stream);
            var br = new AsyncBinaryReader(stream);
            //1
            await bw.WriteAsync(pubBytes.Length);

            await bw.WriteAsync(pubBytes);

            //2
            await bw.WriteAsync(signed.Length);

            await bw.WriteAsync(signed);

            //3
            await bw.WriteAsync(kePubBytes.Length);

            await bw.WriteAsync(kePubBytes);

            // read remote public key and verify signature
            //1
            var remotePubKey   = ECDsa.Create();
            var remotePubBytes = await br.ReadBytesAsync(await br.ReadAssertAsync(120));

            remotePubKey.ImportSubjectPublicKeyInfo(remotePubBytes, out _);
            //2
            var remoteSignature = await br.ReadBytesAsync(await br.ReadAssertAsync(96));

            //3
            var remoteKePub = await br.ReadBytesAsync(await br.ReadAssertAsync(158));

            var remoteEcdh = ECDiffieHellman.Create();

            remoteEcdh.ImportSubjectPublicKeyInfo(remoteKePub, out _);

            // verify signed public key exchange key
            if (!remotePubKey.VerifyData(remoteKePub, remoteSignature, HashAlgorithmName.SHA256))
            {
                throw new CryptographicException("Remote public key does not match hash!");
            }
            // derive shared secret
            var sharedSecret = ecdh.DeriveKeyMaterial(remoteEcdh.PublicKey);

            // return the public key (fingerprint) of the remote, and the hashed shared secret
            return(SHA256.HashData(sharedSecret), remotePubKey.ExportParameters(false).Q);
        }
Example #26
0
        public async Task When_writing_a_bit_set()
        {
            var sut = new Pdb70BitSet();
            sut[0x0] = true;
            sut[0x28] = true;

            var ms = new MemoryStream();
            var writer = new AsyncBinaryWriter(new TestStream(ms));
            await sut.WriteAsync(writer, CancellationToken.None);

            Assert.Equal(new byte[] {
                2, 0, 0, 0,
                1, 0, 0, 0,
                0, 1, 0, 0
            }, ms.ToArray());
        }
Example #27
0
 public AuthWriter(Stream input)
 {
     _writer = new AsyncBinaryWriter(input);
 }
 /// <inheritdoc />
 public JSONStreamEntryInserter([NotNull] AsyncBinaryWriter writer, [NotNull] ILogger <JSONStreamEntryInserter <TDbcEntryType> > logger)
 {
     Writer = writer ?? throw new ArgumentNullException(nameof(writer));
     Logger = logger ?? throw new ArgumentNullException(nameof(logger));
 }