public void ReadWrite_WithWriteReadWrite_HasExpectedBuffer()
        {
            // Assign
            var stream = new CircularStream(BufferInitialSize);

            // Act
            var bufferStub1 = CreateByteArray(4, 12);

            stream.Write(bufferStub1, 0, bufferStub1.Length);

            var bufferOut = new byte[6];

            stream.Read(bufferOut, 0, bufferOut.Length);

            var bufferStub2 = CreateByteArray(6, 6);

            stream.Write(bufferStub2, 0, bufferStub2.Length);

            var bufferRemains = stream.ToArray();

            // Assert
            const string expected = "6600004444446666";
            var          actual   = bufferRemains.GetString();

            Assert.Equal(expected, actual);
        }
        public void ReadWrite_With2SequentialCalls_HasExpectedBuffer()
        {
            // Assign
            var stream = new CircularStream(BufferInitialSize);

            // Act
            var bufferStub = CreateByteArray(4, 6);

            stream.Write(bufferStub, 0, bufferStub.Length);
            stream.Write(bufferStub, 0, bufferStub.Length);
            var bufferRemains = stream.ToArray();

            // Assert
            const string expected = "4444444444440000";
            var          actual   = bufferRemains.GetString();

            Assert.Equal(expected, actual);
        }
示例#3
0
    public void Read_ReadLessThanBufferLength_ReturnsSomeOfTheBuffer()
    {
        // Arrange
        var uut = new CircularStream(2);

        uut.Write(new byte[] { 0, 1 }, 0, 2);
        var result = new byte[1];

        // Act
        uut.Read(result, 0, 1);

        // Assert
        Assert.AreEqual(1, result.Length);
        Assert.AreEqual(0, result[0]);
    }
示例#4
0
    public void Write_DoNotCompletelyFillBuffer_ReturnsJustWhatIsWritten()
    {
        // Arrange
        var uut          = new CircularStream(2);
        var bytesToWrite = new Byte[] { 0 };

        // Act
        uut.Write(bytesToWrite, 111, 222);
        var result = new Byte[1];

        uut.Read(result, 0, 1);

        // Assert
        Assert.AreEqual(1, result.Length);
        Assert.AreEqual(0, result[0]);
    }
示例#5
0
    public void Write_FillPastBuffer_ReturnsJustLengthOfBuffer()
    {
        // Arrange
        var uut          = new CircularStream(2);
        var bytesToWrite = new Byte[] { 0, 1, 2, 3 };

        // Act
        uut.Write(bytesToWrite, 111, 222);
        var result = new Byte[2];

        uut.Read(result, 0, 2);

        // Assert
        Assert.AreEqual(2, result.Length);
        Assert.AreEqual(2, result[0]);
        Assert.AreEqual(3, result[1]);
    }
示例#6
0
    public void Read_PastBuffer_ReturnsCircularly()
    {
        // Arrange
        var uut = new CircularStream(2);

        uut.Write(new byte[] { 0, 1 }, 0, 2);
        var result = new byte[4];

        // Act
        uut.Read(result, 0, 4);

        // Assert
        Assert.AreEqual(4, result.Length);
        Assert.AreEqual(0, result[0]);
        Assert.AreEqual(1, result[1]);
        Assert.AreEqual(0, result[2]);
        Assert.AreEqual(1, result[3]);
    }
示例#7
0
    public void Write_FillBuffer_WritesToBuffer()
    {
        // Arrange
        var uut          = new CircularStream(5);
        var bytesToWrite = new Byte[] { 0, 1, 2, 3, 4 };

        // Act
        uut.Write(bytesToWrite, 111, 222);
        var result = new Byte[5];

        uut.Read(result, 0, 5);

        // Assert
        Assert.AreEqual(0, result[0]);
        Assert.AreEqual(1, result[1]);
        Assert.AreEqual(2, result[2]);
        Assert.AreEqual(3, result[3]);
        Assert.AreEqual(4, result[4]);
    }
示例#8
0
    public void Read_FillBuffer_WritesToBuffer()
    {
        // Arrange
        var uut = new CircularStream(5);

        uut.Write(new byte[] { 0, 1, 2, 3, 4 }, 0, 5);
        var result = new byte[5];

        // Act
        uut.Read(result, 0, 5);

        // Assert
        Assert.AreEqual(5, result.Length);
        Assert.AreEqual(0, result[0]);
        Assert.AreEqual(1, result[1]);
        Assert.AreEqual(2, result[2]);
        Assert.AreEqual(3, result[3]);
        Assert.AreEqual(4, result[4]);
    }
        public async void Read_WithWriteCallAfter_DoesNotThrowTimeoutException()
        {
            // Assign
            var stream = new CircularStream(BufferInitialSize, true, ReadMode.Wait, 1000);

            // Act
            var bufferOut = new byte[6];
            var readTask  = Task.Run(() => stream.Read(bufferOut, 0, bufferOut.Length));

            var bufferStub = CreateByteArray(4, 6);

            stream.Write(bufferStub, 0, bufferStub.Length);

            int bytesRead     = await readTask;
            var bufferRemains = stream.ToArray();

            // Assert
            const string expected = "4444440000000000";
            var          actual   = bufferRemains.GetString();

            Assert.Equal(expected, actual);
            Assert.Equal(bufferOut.Length, bytesRead);
        }
示例#10
0
    private void OnDataReceive(IAsyncResult result)
    {
        lock (this)
        {
            int bytesRead = this.connection.EndReceive(result);

            if (bytesRead > 0)
            {
                // shove data into memory stream
                circStream.Write(this.receiveBuffer, 0, bytesRead);

                // get raw data from circular stream
                byte[] rawData = new byte[circStream.DataAvailable];
                circStream.Read(rawData, 0, rawData.Length);

                // split the message into composite messages
                string rawMessage = System.Text.Encoding.ASCII.GetString(rawData);
                string subMessage = string.Empty;
                int    position   = 0;

                while (position < rawMessage.Length)
                {
                    // see if we have enough to determine the message code
                    if (rawMessage.Length - position >= 3)
                    {
                        string messageCode = rawMessage.Substring(position, 3);

                        if (messageCode == "MSG")
                        {
                            // if its a MSG, then read until the length is satified
                            Regex.Regex regex = new Regex.Regex(@"MSG\s+\S+\s+\S+\s+(?<length>\d+)");
                            Regex.Match match = regex.Match(rawMessage.Substring(position));

                            if (match.Success)
                            {
                                int length      = int.Parse(match.Groups["length"].Value);
                                int endOfHeader = rawMessage.IndexOf("\r\n", position);

                                if (endOfHeader >= 0 && position + endOfHeader + length + 2 <= rawMessage.Length)
                                {
                                    subMessage = rawMessage.Substring(position, endOfHeader + length + 2 - position);
                                }
                                else
                                {
                                    this.SetToDataStream(rawMessage.Substring(position));
                                    break;
                                }
                            }
                            else
                            {
                                // we didnt get enough of the string to determine the message length -
                                // set it to the data stream and wait till the next rush of data
                                this.SetToDataStream(rawMessage.Substring(position));
                                break;
                            }
                        }
                        else
                        {
                            // otherwise it isnt a MSG, so read up until the first \r\n
                            int newPosition = rawMessage.IndexOf("\r\n", position);
                            if (newPosition < 0)
                            {
                                // we dont have the entire message - clear out the left over data stream
                                // and add the incomplete message to the stream
                                this.SetToDataStream(rawMessage.Substring(position));
                                break;
                            }
                            else
                            {
                                newPosition += 2;
                                subMessage   = rawMessage.Substring(position, newPosition - position);
                            }
                        }
                    }
                    else
                    {
                        // we dont even have enough to determine the message code - add it to the data stream
                        // and forget about it
                        this.SetToDataStream(rawMessage.Substring(position));
                        break;
                    }

                    position += subMessage.Length;

                    this.protocol.control.WriteDebug("-----------------------------------------");
                    this.protocol.control.WriteDebug("Received");
                    this.protocol.control.WriteDebug(subMessage);
                    this.protocol.control.WriteDebug("-----------------------------------------");

                    Message message = new Message(subMessage);

                    switch (message.Code)
                    {
                    case "CHL":
                    {
                        // we received a challenge. Respond to it appropriately.
                        string hash = message.Arguments;

                        // md5 encrypt hash
                        hash += md5MagicHash;

                        MD5Encryption encryption = new MD5Encryption();
                        string        md5hash    = encryption.Encrypt(hash);

                        Message responseMessage = Message.ConstructMessage("QRY", @"[email protected] 32" + "\r\n" + md5hash);
                        this.SendMessage(responseMessage, false);
                    }
                    break;
                    }

                    try
                    {
                        // see if theres a transaction ID registered with it
                        if (this.transactionEvents.Contains(message.TransactionID))
                        {
                            Pair pair = (Pair)this.transactionEvents[message.TransactionID];
                            ((ResponseReceivedHandler)pair.First)(this, message, pair.Second);
                        }
                        // else check if the code is registered
                        else if (this.codeEvents.Contains(message.Code))
                        {
                            Pair pair = (Pair)this.codeEvents[message.Code];
                            ((ResponseReceivedHandler)pair.First)(this, message, pair.Second);
                        }
                        // otherwise uses the default message sink
                        else
                        {
                            if (defaultMessageSink != null)
                            {
                                defaultMessageSink(this, message, null);
                            }
                        }
                    }
                    catch
                    {}
                }

                try
                {
                    // restart async call
                    this.connection.BeginReceive(receiveBuffer, new AsyncCallback(OnDataReceive), null);
                }
                catch
                {
                    this.onDisconnect(this, null, null);
                }
            }
            else if (!ExpectingDisconnection)
            {
                this.onDisconnect(this, null, null);
            }
        }
    }