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); }
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; } }
/// <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; }
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)); }
/// <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; }
/// <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); }
/// <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; }