Reader to read values from a socket. Heavily optimized to reduce task creation and byte array allocation
Inheritance: IDisposable
示例#1
0
        protected override async Task InitializeAsync()
        {
            FrameReader reader = Reader;

            ResultOpcode = (ResultOpcode)await reader.ReadIntAsync().ConfigureAwait(false);

            switch (ResultOpcode)
            {
            case ResultOpcode.Void:
                break;

            case ResultOpcode.Rows:
                Schema = await ReadCqlSchemaAsync().ConfigureAwait(false);

                _count = await reader.ReadIntAsync().ConfigureAwait(false);

                break;

            case ResultOpcode.SetKeyspace:
                Keyspace = await reader.ReadStringAsync().ConfigureAwait(false);

                break;

            case ResultOpcode.SchemaChange:
                Change = await reader.ReadStringAsync().ConfigureAwait(false);

                Keyspace = await reader.ReadStringAsync().ConfigureAwait(false);

                Table = await reader.ReadStringAsync().ConfigureAwait(false);

                break;

            case ResultOpcode.Prepared:
                PreparedQueryId = await reader.ReadShortBytesAsync().ConfigureAwait(false);

                Schema = await ReadCqlSchemaAsync().ConfigureAwait(false);

                break;

            default:
                throw new ArgumentException("Unexpected ResultOpcode");
            }

            //_readLock = new SemaphoreSlim(1);
        }
示例#2
0
        protected override async Task InitializeAsync()
        {
            FrameReader stream = Reader;
            var         code   = (ErrorCode)await stream.ReadIntAsync().ConfigureAwait(false);

            string msg = await stream.ReadStringAsync().ConfigureAwait(false);

            switch (code)
            {
            case ErrorCode.Unavailable:
            {
                var cl = (CqlConsistency)await stream.ReadShortAsync().ConfigureAwait(false);

                int required = await stream.ReadIntAsync().ConfigureAwait(false);

                int alive = await stream.ReadIntAsync().ConfigureAwait(false);

                Exception = new UnavailableException(msg, cl, required, alive);
                break;
            }

            case ErrorCode.WriteTimeout:
            {
                var cl = (CqlConsistency)await stream.ReadShortAsync().ConfigureAwait(false);

                int received = await stream.ReadIntAsync().ConfigureAwait(false);

                int blockFor = await stream.ReadIntAsync().ConfigureAwait(false);

                string writeType = await stream.ReadStringAsync().ConfigureAwait(false);

                Exception = new WriteTimeOutException(msg, cl, received, blockFor, writeType);
                break;
            }

            case ErrorCode.ReadTimeout:
            {
                var cl = (CqlConsistency)await stream.ReadShortAsync().ConfigureAwait(false);

                int received = await stream.ReadIntAsync().ConfigureAwait(false);

                int blockFor = await stream.ReadIntAsync().ConfigureAwait(false);

                bool dataPresent = 0 != await stream.ReadByteAsync().ConfigureAwait(false);

                Exception = new ReadTimeOutException(msg, cl, received, blockFor, dataPresent);
                break;
            }

            case ErrorCode.Syntax:
                Exception = new SyntaxException(msg);
                break;

            case ErrorCode.Unauthorized:
                Exception = new UnauthorizedException(msg);
                break;

            case ErrorCode.Invalid:
                Exception = new InvalidException(msg);
                break;

            case ErrorCode.AlreadyExists:
                string keyspace = await stream.ReadStringAsync().ConfigureAwait(false);

                string table = await stream.ReadStringAsync().ConfigureAwait(false);

                Exception = new AlreadyExistsException(msg, keyspace, table);
                break;

            case ErrorCode.Unprepared:
                byte[] unknownId = await stream.ReadShortBytesAsync().ConfigureAwait(false);

                Exception = new UnpreparedException(msg, unknownId);
                break;

            default:
                Exception = new ProtocolException(code, msg);
                break;
            }
        }
示例#3
0
        /// <summary>
        /// Reads the CqlType
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>a CqlType</returns>
        private static async Task<CqlType> ReadCqlType(FrameReader reader)
        {
            //read typeCode
            var colType = (CqlTypeCode)await reader.ReadShortAsync().AutoConfigureAwait();
            CqlType type;
            switch(colType)
            {
                case CqlTypeCode.Custom:
                    var colCustom = await reader.ReadStringAsync().AutoConfigureAwait();
                    type = CqlType.CreateType(colCustom);
                    break;

                case CqlTypeCode.List:
                case CqlTypeCode.Set:
                    var colValueType = await ReadCqlType(reader).AutoConfigureAwait();
                    type = CqlType.CreateType(colType, colValueType);
                    break;

                case CqlTypeCode.Map:
                    var colKeyType = await ReadCqlType(reader).AutoConfigureAwait();
                    var colValType = await ReadCqlType(reader).AutoConfigureAwait();
                    type = CqlType.CreateType(colType, colKeyType, colValType);
                    break;

                case CqlTypeCode.UserDefinedType:
                    var keyspace = await reader.ReadStringAsync().AutoConfigureAwait();
                    var name = await reader.ReadStringAsync().AutoConfigureAwait();
                    var fieldCount = await reader.ReadShortAsync().AutoConfigureAwait();
                    var fieldNames = new List<string>(fieldCount);
                    var fieldTypes = new List<CqlType>(fieldCount);
                    for(int i = 0; i < fieldCount; i++)
                    {
                        fieldNames.Add(await reader.ReadStringAsync().AutoConfigureAwait());
                        fieldTypes.Add(await ReadCqlType(reader).AutoConfigureAwait());
                    }

                    type = CqlType.CreateType(colType, keyspace, name, fieldNames, fieldTypes);
                    break;

                case CqlTypeCode.Tuple:
                    var tupleItems = await reader.ReadShortAsync().AutoConfigureAwait();
                    var tupleItemTypes = new object[tupleItems];
                    for(int i = 0; i < tupleItems; i++)
                    {
                        tupleItemTypes[i] = await ReadCqlType(reader).AutoConfigureAwait();
                    }

                    type = CqlType.CreateType(colType, tupleItemTypes);
                    break;

                default:
                    type = CqlType.CreateType(colType);
                    break;
            }
            return type;
        }
示例#4
0
        internal async Task <CqlSchema> ReadCqlSchemaAsync()
        {
            FrameReader reader = Reader;
            var         flags  = (MetadataFlags)await reader.ReadIntAsync().ConfigureAwait(false);

            bool globalTablesSpec = 0 != (flags & MetadataFlags.GlobalTablesSpec);

            int colCount = await reader.ReadIntAsync().ConfigureAwait(false);

            string keyspace = null;
            string table    = null;

            if (globalTablesSpec)
            {
                keyspace = await reader.ReadStringAsync().ConfigureAwait(false);

                table = await reader.ReadStringAsync().ConfigureAwait(false);
            }

            var columnSpecs = new List <CqlColumn>(colCount);

            for (int colIdx = 0; colIdx < colCount; ++colIdx)
            {
                string colKeyspace = keyspace;
                string colTable    = table;
                if (!globalTablesSpec)
                {
                    colKeyspace = await reader.ReadStringAsync().ConfigureAwait(false);

                    colTable = await reader.ReadStringAsync().ConfigureAwait(false);
                }
                string colName = await reader.ReadStringAsync().ConfigureAwait(false);

                var colType = (CqlType)await reader.ReadShortAsync().ConfigureAwait(false);

                string  colCustom    = null;
                CqlType?colKeyType   = null;
                CqlType?colValueType = null;
                switch (colType)
                {
                case CqlType.Custom:
                    colCustom = await reader.ReadStringAsync().ConfigureAwait(false);

                    break;

                case CqlType.List:
                case CqlType.Set:
                    colValueType = (CqlType)await reader.ReadShortAsync().ConfigureAwait(false);

                    break;

                case CqlType.Map:
                    colKeyType = (CqlType)await reader.ReadShortAsync().ConfigureAwait(false);

                    colValueType = (CqlType)await reader.ReadShortAsync().ConfigureAwait(false);

                    break;
                }

                columnSpecs.Add(new CqlColumn(colIdx, colKeyspace, colTable, colName, colType, colCustom,
                                              colKeyType, colValueType));
            }

            return(new CqlSchema(columnSpecs));
        }
示例#5
0
        /// <summary>
        ///   Reads a packet from a stream.
        /// </summary>
        /// <param name="stream"> The stream. </param>
        /// <returns> </returns>
        internal static async Task<Frame> FromStream(Stream stream)
        {
            //read header
            int read = 0;
            var header = new byte[8];
            while (read < 8)
                read += await stream.ReadAsync(header, read, 8 - read).ConfigureAwait(false);

            //get length
            if (BitConverter.IsLittleEndian) Array.Reverse(header, 4, 4);
            int length = BitConverter.ToInt32(header, 4);

            Frame frame;
            switch ((FrameOpcode)header[3])
            {
                case FrameOpcode.Error:
                    frame = new ErrorFrame();
                    break;
                case FrameOpcode.Ready:
                    frame = new ReadyFrame();
                    break;
                case FrameOpcode.Authenticate:
                    frame = new AuthenticateFrame();
                    break;
                case FrameOpcode.Supported:
                    frame = new SupportedFrame();
                    break;
                case FrameOpcode.Result:
                    frame = new ResultFrame();
                    break;
                case FrameOpcode.Event:
                    frame = new EventFrame();
                    break;
                default:
                    throw new ProtocolException(0, "Unexpected OpCode received.");
            }

            frame.Version = (FrameVersion)header[0];
            frame.Flags = (FrameFlags)header[1];
            frame.Stream = unchecked((sbyte)header[2]);
            frame.OpCode = (FrameOpcode)header[3];
            frame.Length = length;

            //wrap the stream in a window, that will be completely read when disposed
            var reader = new FrameReader(stream, length);
            frame.Reader = reader;

            //decompress the contents of the frame (implicity loads the entire frame body!)
            if (frame.Flags.HasFlag(FrameFlags.Compression))
                await reader.DecompressAsync();

            //read tracing id if set
            if (frame.Flags.HasFlag(FrameFlags.Tracing))
                frame.TracingId = await reader.ReadUuidAsync().ConfigureAwait(false);

            await frame.InitializeAsync().ConfigureAwait(false);

            return frame;
        }
示例#6
0
        /// <summary>
        ///   Reads a packet from a stream.
        /// </summary>
        /// <param name="stream"> The stream. </param>
        /// <returns> </returns>
        internal static async Task <Frame> FromStream(Stream stream)
        {
            //read header
            int read   = 0;
            var header = new byte[8];

            while (read < 8)
            {
                read += await stream.ReadAsync(header, read, 8 - read).ConfigureAwait(false);
            }

            //get length
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(header, 4, 4);
            }
            int length = BitConverter.ToInt32(header, 4);

            Frame frame;

            switch ((FrameOpcode)header[3])
            {
            case FrameOpcode.Error:
                frame = new ErrorFrame();
                break;

            case FrameOpcode.Ready:
                frame = new ReadyFrame();
                break;

            case FrameOpcode.Authenticate:
                frame = new AuthenticateFrame();
                break;

            case FrameOpcode.Supported:
                frame = new SupportedFrame();
                break;

            case FrameOpcode.Result:
                frame = new ResultFrame();
                break;

            case FrameOpcode.Event:
                frame = new EventFrame();
                break;

            default:
                throw new ProtocolException(0, "Unexpected OpCode received.");
            }

            frame.Version = (FrameVersion)header[0];
            frame.Flags   = (FrameFlags)header[1];
            frame.Stream  = unchecked ((sbyte)header[2]);
            frame.OpCode  = (FrameOpcode)header[3];
            frame.Length  = length;

            //wrap the stream in a window, that will be completely read when disposed
            var reader = new FrameReader(stream, length);

            frame.Reader = reader;

            //decompress the contents of the frame (implicity loads the entire frame body!)
            if (frame.Flags.HasFlag(FrameFlags.Compression))
            {
                await reader.DecompressAsync();
            }

            //read tracing id if set
            if (frame.Flags.HasFlag(FrameFlags.Tracing))
            {
                frame.TracingId = await reader.ReadUuidAsync().ConfigureAwait(false);
            }

            await frame.InitializeAsync().ConfigureAwait(false);

            return(frame);
        }
示例#7
0
文件: Frame.cs 项目: reuzel/CqlSharp
        /// <summary>
        /// Reads a packet from a stream.
        /// </summary>
        /// <param name="stream"> The stream. </param>
        /// <returns> </returns>
        internal static async Task<Frame> FromStream(Stream stream)
        {
            int read = 0;
            var header = new byte[9];

            //read version byte first
            if(Scheduler.RunningSynchronously)
                read += stream.Read(header, 0, 1);
            else
                read += await stream.ReadAsync(header, 0, 1).AutoConfigureAwait();

            //return null if the stream was closed by Cassandra
            if(read == 0)
                return null;

            //distill version
            var protocolVersion = (byte)(header[0] & 0x7f);

            //read remaining header bytes
            int headerSize = protocolVersion <= 2 ? 8 : 9;
            while(read < headerSize)
            {
                if(Scheduler.RunningSynchronously)
                    read += stream.Read(header, read, headerSize - read);
                else
                    read += await stream.ReadAsync(header, read, headerSize - read).AutoConfigureAwait();

                //check if we are not end-of-stream
                if(read == 0 && read < headerSize)
                    throw new IOException("Unexpected end of stream reached");
            }

            Frame frame;
            if(protocolVersion <= 2)
            {
                var opcode = (FrameOpcode)header[3];
                frame = GetFrameFromOpcode(protocolVersion, opcode);

                frame.ProtocolVersion = protocolVersion;
                frame.IsRequest = (header[0] & 0x80) == 0;
                frame.Flags = (FrameFlags)header[1];
                frame.Stream = unchecked((sbyte)header[2]);
                frame.OpCode = opcode;
                frame.Length = header.ToInt(4);
            }
            else
            {
                var opcode = (FrameOpcode)header[4];
                frame = GetFrameFromOpcode(protocolVersion, opcode);

                frame.ProtocolVersion = protocolVersion;
                frame.IsRequest = (header[0] & 0x80) == 0;
                frame.Flags = (FrameFlags)header[1];
                frame.Stream = unchecked((short)header.ToShort(2));
                frame.OpCode = opcode;
                frame.Length = header.ToInt(5);
            }

            //wrap the stream in a window, that will be completely read when disposed
            var reader = new FrameReader(stream, frame.Length);
            frame.Reader = reader;

            return frame;
        }