public async Task <T> Read <T>() where T : new() { const int sizeSize = sizeof(int); const int codeSize = sizeof(byte); var buffer = _blockingBufferManager.GetBuffer(); try { await GetConnectedSocket().ConfigureAwait(false); var headerBuffer = new ArraySegment <byte>(buffer.Array, buffer.Offset, sizeSize + codeSize); await ReceiveAsync(headerBuffer).ConfigureAwait(false); var messageLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(headerBuffer.Array, headerBuffer.Offset)); var messageCode = (MessageCode)headerBuffer.Array[headerBuffer.Offset + sizeSize]; if (messageCode == MessageCode.ErrorResp) { if (messageLength - codeSize < 1) { var error = new RpbErrorResp(); throw new RiakException(error.errcode, error.errmsg.FromRiakString(), false); } if (messageLength > buffer.Count) { throw new RiakInvalidDataException(0); } var errorBuffer = new ArraySegment <byte>(headerBuffer.Array, headerBuffer.Offset + sizeSize + codeSize, messageLength - codeSize); await ReceiveAsync(errorBuffer).ConfigureAwait(false); using (var stream = new MemoryStream(errorBuffer.Array, errorBuffer.Offset, errorBuffer.Count)) { var error = Serializer.Deserialize <RpbErrorResp>(stream); throw new RiakException(error.errcode, error.errmsg.FromRiakString(), false); } } if (messageLength > buffer.Count) { throw new RiakInvalidDataException(0); } if (!MessageCodeToTypeMap.ContainsKey(messageCode)) { throw new RiakInvalidDataException((byte)messageCode); } if (messageLength > buffer.Count) { throw new RiakInvalidDataException(0); } #if DEBUG // This message code validation is here to make sure that the caller // is getting exactly what they expect. This "could" be removed from // production code, but it's a good thing to have in here for dev. if (MessageCodeToTypeMap[messageCode] != typeof(T)) { throw new InvalidOperationException( string.Format("Attempt to decode message to type '{0}' when received type '{1}'.", typeof(T).Name, MessageCodeToTypeMap[messageCode].Name)); } #endif if (messageLength - codeSize <= 1) { return(new T()); } var bodyBuffer = new ArraySegment <byte>(headerBuffer.Array, headerBuffer.Offset + sizeSize + codeSize, messageLength - codeSize); await ReceiveAsync(bodyBuffer).ConfigureAwait(false); using (var stream = new MemoryStream(bodyBuffer.Array, bodyBuffer.Offset, bodyBuffer.Count)) { var message = Serializer.Deserialize <T>(stream); return(message); } } catch (RiakException) { if (_socket != null) { _socket.Close(); _socket = null; } throw; } catch (SocketException) { if (_socket != null) { _socket.Close(); _socket = null; } throw; } finally { _blockingBufferManager.ReleaseBuffer(buffer); } }
public async Task <MessageCode> Read(MessageCode expectedCode) { const int sizeSize = sizeof(int); const int codeSize = sizeof(byte); var buffer = _blockingBufferManager.GetBuffer(); try { await GetConnectedSocket().ConfigureAwait(false); var headerBuffer = new ArraySegment <byte>(buffer.Array, buffer.Offset, sizeSize + codeSize); await ReceiveAsync(headerBuffer).ConfigureAwait(false); var messageLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(headerBuffer.Array, headerBuffer.Offset)); var messageCode = (MessageCode)headerBuffer.Array[headerBuffer.Offset + sizeSize]; if (messageCode == MessageCode.ErrorResp) { if (messageLength - codeSize < 1) { var error = new RpbErrorResp(); throw new RiakException(error.errcode, error.errmsg.FromRiakString(), false); } var errorBuffer = new ArraySegment <byte>(headerBuffer.Array, headerBuffer.Offset + sizeSize + codeSize, messageLength - codeSize); await ReceiveAsync(errorBuffer).ConfigureAwait(false); using (var stream = new MemoryStream(errorBuffer.Array, errorBuffer.Offset, errorBuffer.Count)) { var error = Serializer.Deserialize <RpbErrorResp>(stream); throw new RiakException(error.errcode, error.errmsg.FromRiakString(), false); } } if (expectedCode != messageCode) { throw new RiakException("Expected return code {0} received {1}".Fmt(expectedCode, messageCode)); } return(messageCode); } catch (RiakException) { if (_socket != null) { _socket.Close(); _socket = null; } throw; } catch (SocketException) { if (_socket != null) { _socket.Close(); _socket = null; } throw; } finally { _blockingBufferManager.ReleaseBuffer(buffer); } }