public static int Write <T>(T value, ref PreservedBuffer <byte> destination, uint offset = 0u, MemoryStream temporaryStream = null, CompressionMethod compression = CompressionMethod.DefaultOrNone) { var buffer = destination.Buffer; return(Write(value, ref buffer, offset, temporaryStream)); }
public HttpRequestHeaders Headers; // yes, naked field - internal type, so not too exposed; allows for "ref" without copy public HttpRequest(PreservedBuffer method, PreservedBuffer path, PreservedBuffer httpVersion, Dictionary <string, PreservedBuffer> headers) { Method = method; Path = path; HttpVersion = httpVersion; Headers = new HttpRequestHeaders(headers); }
public static unsafe int Read <T>(PreservedBuffer <byte> source, uint offset, ref T value) { var fixedMemory = default(FixedMemory <byte>); try { void *pointer; if (!source.Buffer.TryGetPointer(out pointer)) { fixedMemory = source.Fix(); ArraySegment <byte> tmpArraySegment; if (fixedMemory.Buffer.TryGetArray(out tmpArraySegment)) { pointer = (void *)Marshal.UnsafeAddrOfPinnedArrayElement(tmpArraySegment.Array, tmpArraySegment.Offset + (int)offset); } } return(Read((IntPtr)pointer, ref value)); } finally { if (!fixedMemory.Equals(default(FixedMemory <byte>))) { fixedMemory.Dispose(); } } }
public unsafe static int Write <T>(T value, ref PreservedBuffer <byte> destination, uint offset = 0u, MemoryStream temporaryStream = null, CompressionMethod compression = CompressionMethod.DefaultOrNone) { var tmpArraySegment = default(ArraySegment <byte>); var fixedMemory = default(FixedMemory <byte>); try { void *pointer; if (!destination.Buffer.TryGetPointer(out pointer)) { fixedMemory = destination.Fix(); if (fixedMemory.Buffer.TryGetArray(out tmpArraySegment)) { pointer = (void *)Marshal.UnsafeAddrOfPinnedArrayElement(tmpArraySegment.Array, tmpArraySegment.Offset); } } var db = new DirectBuffer(tmpArraySegment.Count, pointer); return(Write(value, ref db, offset, temporaryStream)); } finally { if (!fixedMemory.Equals(default(FixedMemory <byte>))) { fixedMemory.Dispose(); } } }
public static unsafe int Read <T>(PreservedBuffer <byte> source, uint offset, out T value) { var handle = source.Buffer.Retain(true); try { return(Read((IntPtr)handle.PinnedPointer, out value)); } finally { handle.Dispose(); } }
private static object ReadSimpleStringAsync(this ReadableBuffer buffer) { // Find \n ReadCursor delim; ReadableBuffer line; if (!buffer.TrySliceTo((byte)'\r', (byte)'\n', out line, out delim)) { return(new RedisErrorString("Unable to read line")); } PreservedBuffer preservedBuffer = line.Preserve(); // Move the buffer to the rest buffer = buffer.Slice(delim).Slice(2); return(preservedBuffer); }
public static unsafe int Read <T>(PreservedBuffer <byte> source, uint offset, out T value) { var handle = default(BufferHandle); try { if (!source.Buffer.TryGetPointer(out void *pointer)) { handle = source.Buffer.Pin(); if (source.Buffer.TryGetArray(out ArraySegment <byte> tmpArraySegment)) { pointer = (void *)Marshal.UnsafeAddrOfPinnedArrayElement(tmpArraySegment.Array, tmpArraySegment.Offset + (int)offset); } } return(Read((IntPtr)pointer, out value)); } finally { handle.Free(); } }
private async Task ProcessSends() { while (true) { var result = await _output.ReadAsync(); var buffer = result.Buffer; if (buffer.IsEmpty && result.IsCompleted) { break; } var enumerator = buffer.GetEnumerator(); if (enumerator.MoveNext()) { var current = enumerator.Current; while (enumerator.MoveNext()) { var next = enumerator.Current; await SendAsync(current, endOfMessage : false); current = next; } await PreviousSendingComplete; _sendingBuffer = buffer.Preserve(); await SendAsync(current, endOfMessage : true); } _output.Advance(buffer.End); } _output.CompleteReader(); }
internal static async Task <HttpRequest> ParseHttpRequest(IPipeReader input) { PreservedBuffer Method = default(PreservedBuffer), Path = default(PreservedBuffer), HttpVersion = default(PreservedBuffer); Dictionary <string, PreservedBuffer> Headers = new Dictionary <string, PreservedBuffer>(); try { ParsingState _state = ParsingState.StartLine; bool needMoreData = true; while (needMoreData) { var read = await input.ReadAsync(); var buffer = read.Buffer; var consumed = buffer.Start; needMoreData = true; try { if (buffer.IsEmpty && read.IsCompleted) { throw new EndOfStreamException(); } if (_state == ParsingState.StartLine) { // Find \n ReadCursor delim; ReadableBuffer startLine; if (!buffer.TrySliceTo((byte)'\r', (byte)'\n', out startLine, out delim)) { continue; } // Move the buffer to the rest buffer = buffer.Slice(delim).Slice(2); ReadableBuffer method; if (!startLine.TrySliceTo((byte)' ', out method, out delim)) { throw new Exception(); } Method = method.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); ReadableBuffer path; if (!startLine.TrySliceTo((byte)' ', out path, out delim)) { throw new Exception(); } Path = path.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); var httpVersion = startLine; if (httpVersion.IsEmpty) { throw new Exception(); } HttpVersion = httpVersion.Preserve(); _state = ParsingState.Headers; consumed = buffer.Start; } // Parse headers // key: value\r\n while (!buffer.IsEmpty) { var ch = Peek(ref buffer); if (ch == -1) { break; } if (ch == '\r') { // Check for final CRLF. buffer = buffer.Slice(1); ch = Peek(ref buffer); buffer = buffer.Slice(1); if (ch == -1) { break; } else if (ch == '\n') { consumed = buffer.Start; needMoreData = false; break; } // Headers don't end in CRLF line. throw new Exception(); } var headerName = default(ReadableBuffer); var headerValue = default(ReadableBuffer); // End of the header // \n ReadCursor delim; ReadableBuffer headerPair; if (!buffer.TrySliceTo((byte)'\n', out headerPair, out delim)) { break; } buffer = buffer.Slice(delim).Slice(1); // : if (!headerPair.TrySliceTo((byte)':', out headerName, out delim)) { throw new Exception(); } headerName = headerName.TrimStart(); headerPair = headerPair.Slice(delim).Slice(1); // \r if (!headerPair.TrySliceTo((byte)'\r', out headerValue, out delim)) { // Bad request throw new Exception(); } headerValue = headerValue.TrimStart(); Headers[ToHeaderKey(ref headerName)] = headerValue.Preserve(); // Move the consumed consumed = buffer.Start; } } finally { input.Advance(consumed); } } var result = new HttpRequest(Method, Path, HttpVersion, Headers); Method = Path = HttpVersion = default(PreservedBuffer); Headers = null; return(result); } finally { Method.Dispose(); Path.Dispose(); HttpVersion.Dispose(); if (Headers != null) { foreach (var pair in Headers) { pair.Value.Dispose(); } } } }
public ParseResult ParseRequest(ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) { consumed = buffer.Start; examined = buffer.Start; if (_state == ParsingState.StartLine) { if (!buffer.TrySliceTo((byte)'\r', (byte)'\n', out ReadableBuffer startLine, out ReadCursor delim)) { return(ParseResult.Incomplete); } // Move the buffer to the rest buffer = buffer.Slice(delim).Slice(2); if (!startLine.TrySliceTo((byte)' ', out ReadableBuffer method, out delim)) { return(ParseResult.BadRequest); } _method = method.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); if (!startLine.TrySliceTo((byte)' ', out ReadableBuffer path, out delim)) { return(ParseResult.BadRequest); } _path = path.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); var httpVersion = startLine; if (httpVersion.IsEmpty) { return(ParseResult.BadRequest); } _httpVersion = httpVersion.Preserve(); _state = ParsingState.Headers; consumed = buffer.Start; examined = buffer.Start; } // Parse headers // key: value\r\n while (!buffer.IsEmpty) { var headerValue = default(ReadableBuffer); if (!buffer.TrySliceTo((byte)'\r', (byte)'\n', out ReadableBuffer headerPair, out ReadCursor delim)) { return(ParseResult.Incomplete); } buffer = buffer.Slice(delim).Slice(2); consumed = buffer.Start; examined = buffer.Start; // End of headers if (headerPair.IsEmpty) { return(ParseResult.Complete); } // : if (!headerPair.TrySliceTo((byte)':', out ReadableBuffer headerName, out delim)) { return(ParseResult.BadRequest); } headerName = headerName.TrimStart(); headerPair = headerPair.Slice(delim).Slice(1); headerValue = headerPair.TrimStart(); RequestHeaders.SetHeader(ref headerName, ref headerValue); } return(ParseResult.Incomplete); }
public unsafe void Write( UvStreamHandle handle, ReadableBuffer buffer, Action <UvWriteReq, int, object> callback, object state) { try { // Preserve the buffer for the async call _buffer = buffer.Preserve(); buffer = _buffer.Buffer; int nBuffers = 0; if (buffer.IsSingleSpan) { nBuffers = 1; } else { foreach (var span in buffer) { nBuffers++; } } // add GCHandle to keeps this SafeHandle alive while request processing _pins.Add(GCHandle.Alloc(this, GCHandleType.Normal)); var pBuffers = (Uv.uv_buf_t *)_bufs; if (nBuffers > BUFFER_COUNT) { // create and pin buffer array when it's larger than the pre-allocated one var bufArray = new Uv.uv_buf_t[nBuffers]; var gcHandle = GCHandle.Alloc(bufArray, GCHandleType.Pinned); _pins.Add(gcHandle); pBuffers = (Uv.uv_buf_t *)gcHandle.AddrOfPinnedObject(); } if (nBuffers == 1) { var memory = buffer.First; void *pointer; if (memory.TryGetPointer(out pointer)) { pBuffers[0] = Libuv.buf_init((IntPtr)pointer, memory.Length); } else { throw new InvalidOperationException("Memory needs to be pinned"); } } else { int i = 0; void *pointer; foreach (var memory in buffer) { if (memory.TryGetPointer(out pointer)) { pBuffers[i++] = Libuv.buf_init((IntPtr)pointer, memory.Length); } else { throw new InvalidOperationException("Memory needs to be pinned"); } } } _callback = callback; _state = state; _uv.write(this, handle, pBuffers, nBuffers, _uv_write_cb); } catch { _callback = null; _state = null; _buffer.Dispose(); Unpin(this); throw; } }
public ParseResult ParseRequest(ref ReadableBuffer buffer) { if (_state == ParsingState.StartLine) { // Find \n ReadCursor delim; ReadableBuffer startLine; if (!buffer.TrySliceTo((byte)'\r', (byte)'\n', out startLine, out delim)) { return ParseResult.Incomplete; } // Move the buffer to the rest buffer = buffer.Slice(delim).Slice(2); ReadableBuffer method; if (!startLine.TrySliceTo((byte)' ', out method, out delim)) { return ParseResult.BadRequest; } _method = method.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); ReadableBuffer path; if (!startLine.TrySliceTo((byte)' ', out path, out delim)) { return ParseResult.BadRequest; } _path = path.Preserve(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); var httpVersion = startLine; if (httpVersion.IsEmpty) { return ParseResult.BadRequest; } _httpVersion = httpVersion.Preserve(); _state = ParsingState.Headers; } // Parse headers // key: value\r\n while (!buffer.IsEmpty) { var headerName = default(ReadableBuffer); var headerValue = default(ReadableBuffer); // End of the header // \n ReadCursor delim; ReadableBuffer headerPair; if (!buffer.TrySliceTo((byte)'\r', (byte)'\n', out headerPair, out delim)) { return ParseResult.Incomplete; } buffer = buffer.Slice(delim).Slice(2); // End of headers if (headerPair.IsEmpty) { return ParseResult.Complete; } // : if (!headerPair.TrySliceTo((byte)':', out headerName, out delim)) { return ParseResult.BadRequest; } headerName = headerName.TrimStart(); headerPair = headerPair.Slice(delim).Slice(1); headerValue = headerPair.TrimStart(); RequestHeaders.SetHeader(ref headerName, ref headerValue); } return ParseResult.Incomplete; }
private async Task ProcessSends() { while (true) { var result = await _output.ReadAsync(); var buffer = result.Buffer; if (buffer.IsEmpty && result.IsCompleted) { break; } var enumerator = buffer.GetEnumerator(); if (enumerator.MoveNext()) { var current = enumerator.Current; while (enumerator.MoveNext()) { var next = enumerator.Current; await SendAsync(current, endOfMessage: false); current = next; } await PreviousSendingComplete; _sendingBuffer = buffer.Preserve(); await SendAsync(current, endOfMessage: true); } _output.Advance(buffer.End); } _output.CompleteReader(); }
public unsafe void Write( UvStreamHandle handle, ReadableBuffer buffer, Action<UvWriteReq, int, object> callback, object state) { try { // Preserve the buffer for the async call _buffer = buffer.Preserve(); buffer = _buffer.Buffer; int nBuffers = 0; if (buffer.IsSingleSpan) { nBuffers = 1; } else { foreach (var span in buffer) { nBuffers++; } } // add GCHandle to keeps this SafeHandle alive while request processing _pins.Add(GCHandle.Alloc(this, GCHandleType.Normal)); var pBuffers = (Uv.uv_buf_t*)_bufs; if (nBuffers > BUFFER_COUNT) { // create and pin buffer array when it's larger than the pre-allocated one var bufArray = new Uv.uv_buf_t[nBuffers]; var gcHandle = GCHandle.Alloc(bufArray, GCHandleType.Pinned); _pins.Add(gcHandle); pBuffers = (Uv.uv_buf_t*)gcHandle.AddrOfPinnedObject(); } if (nBuffers == 1) { var memory = buffer.First; void* pointer; if (memory.TryGetPointer(out pointer)) { pBuffers[0] = Libuv.buf_init((IntPtr)pointer, memory.Length); } else { throw new InvalidOperationException("Memory needs to be pinned"); } } else { int i = 0; void* pointer; foreach (var memory in buffer) { if (memory.TryGetPointer(out pointer)) { pBuffers[i++] = Libuv.buf_init((IntPtr)pointer, memory.Length); } else { throw new InvalidOperationException("Memory needs to be pinned"); } } } _callback = callback; _state = state; _uv.write(this, handle, pBuffers, nBuffers, _uv_write_cb); } catch { _callback = null; _state = null; _buffer.Dispose(); Unpin(this); throw; } }