Ejemplo n.º 1
0
        public static async Task <List <Command> > DeserializeAsync(Stream stream)
        {
            Memory <byte> buffer = new byte[8192];
            int           bytesRead;
            var           protocolObjectBuffer             = new MessageProtocolObject[1024];
            Memory <MessageProtocolObject> protocolObjects = protocolObjectBuffer;
            var           parserIndex     = 0;
            Memory <byte> remainingBuffer = new byte[0];

            while ((bytesRead = await stream.ReadAsync(buffer).ConfigureAwait(false)) > 0)
            {
                var(currentParserIndex, remeaningBufferLength) = ParseProtocolObjects(remainingBuffer.Span, buffer.Span.Slice(0, bytesRead),
                                                                                      protocolObjects.Slice(parserIndex),
                                                                                      () =>
                {
                    Array.Resize(ref protocolObjectBuffer, protocolObjectBuffer.Length + 1024);
                    protocolObjects = protocolObjectBuffer;
                });
                parserIndex    += currentParserIndex;
                remainingBuffer = buffer.Slice(bytesRead - remeaningBufferLength, remeaningBufferLength);
            }
            return(ParseCommands(protocolObjects.Slice(0, parserIndex)));
        }
Ejemplo n.º 2
0
        private MessageProtocolObject ReadProtocolObject(byte firstByte)
        {
            var commandStartPosition = _currentPosition - 1;

            switch (firstByte)
            {
                #region Simple String
            case (byte)TokenType.String:
            {
                if (!ReadUntil(new[] { (byte)TokenType.Separator }, out var bytes))
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                return(new StringProtocolObject()
                    {
                        Value = Encoding.UTF8.GetString(bytes)
                    });
            }

                #endregion
                #region Blob
            case (byte)TokenType.Blob:
            {
                if (!ReadInteger(out var length))
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ReadBytes(length, out var bytes))
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                return(new BlobProtocolObject()
                    {
                        Bytes = bytes.ToArray()
                    });
            }

                #endregion

                #region Error

            case (byte)TokenType.Error:
            {
                if (!ReadInteger(out var length))
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ReadAsciiString(8, out var errorCode))
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ReadUtf8String(length, out var errorMessage))
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                return(new ErrorProtocolObject()
                    {
                        Code = errorCode,
                        Message = errorMessage
                    });
            }

                #endregion

                #region Integer

            case (byte)TokenType.Integer:
            {
                if (!ReadInteger(out var value))
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                return(new IntegerProtocolObject()
                    {
                        Value = value
                    });
            }

                #endregion

                #region Long

            case (byte)TokenType.Long:
            {
                if (!ReadLong(out var value))
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                return(new LongProtocolObject()
                    {
                        Value = value
                    });
            }

                #endregion

                #region Double

            case (byte)TokenType.Double:
            {
                if (!ReadDouble(out var value))
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                return(new DoubleProtocolObject()
                    {
                        Value = value
                    });
            }

                #endregion

                #region Null

            case (byte)TokenType.Null:
            {
                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                return(new NullProtocolObject());
            }

                #endregion

                #region Boolean

            case (byte)TokenType.True:
            {
                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                return(new BooleanProtocolObject
                    {
                        Value = true
                    });
            }

            case (byte)TokenType.False:
            {
                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                return(new BooleanProtocolObject
                    {
                        Value = false
                    });
            }

                #endregion

                #region Array

            case (byte)TokenType.Array:
            {
                if (!ReadInteger(out var count))
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                var items = new MessageProtocolObject[count];
                for (var i = 0; i < count; i++)
                {
                    if (!ReadNextByte(out var arrayItemFirstByte))
                    {
                        //EOB
                        _currentPosition = commandStartPosition;
                        return(null);
                    }

                    var item = ReadProtocolObject(arrayItemFirstByte);
                    if (item == null)
                    {
                        //EOB
                        _currentPosition = commandStartPosition;
                        return(null);
                    }

                    items[i] = item;
                }

                return(new ArrayProtocolObject
                    {
                        Items = items
                    });
            }

                #endregion

                #region Map

            case (byte)TokenType.Map:
            {
                if (!ReadInteger(out var count))
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                if (!ExpectSeparator())
                {
                    //EOB
                    _currentPosition = commandStartPosition;
                    return(null);
                }

                var items = new KeyValuePair <MessageProtocolObject, MessageProtocolObject> [count];
                for (var i = 0; i < count; i++)
                {
                    if (!ReadNextByte(out var keyFirstByte))
                    {
                        //EOB
                        _currentPosition = commandStartPosition;
                        return(null);
                    }

                    var key = ReadProtocolObject(keyFirstByte);
                    if (key == null)
                    {
                        //EOB
                        _currentPosition = commandStartPosition;
                        return(null);
                    }

                    if (!ReadNextByte(out var valueFirstByte))
                    {
                        //EOB
                        _currentPosition = commandStartPosition;
                        return(null);
                    }

                    var value = ReadProtocolObject(valueFirstByte);
                    if (value == null)
                    {
                        //EOB
                        _currentPosition = commandStartPosition;
                        return(null);
                    }

                    items[i] = new KeyValuePair <MessageProtocolObject, MessageProtocolObject>(key, value);
                }

                return(new MapProtocolObject
                    {
                        Items = items
                    });
            }

                #endregion


            default:
                throw new SyntaxErrorException($"Invalid start character #{firstByte} at {{0}}.", _currentPosition);
            }
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Handles the writing of <see cref="MessageProtocolObject"/>
 /// </summary>
 /// <param name="protocolObject"></param>
 protected abstract void HandleWrite(MessageProtocolObject protocolObject);
Ejemplo n.º 4
0
 /// <inheritdoc />
 public virtual void Write(MessageProtocolObject protocolObject)
 {
     HandleWrite(protocolObject);
 }
Ejemplo n.º 5
0
 /// <inheritdoc />
 protected override void HandleWrite(MessageProtocolObject protocolObject)
 {
     _items.Add(protocolObject);
 }