internal unsafe GamepadState(IGamepad gamepad, MemoryPool <byte> pool) { Name = gamepad.Name; Index = gamepad.Index; IsConnected = gamepad.IsConnected; var srcButtons = gamepad.Buttons; var srcThumbsticks = gamepad.Thumbsticks; var srcTriggers = gamepad.Triggers; _buttons = pool.Rent((_buttonCount = srcButtons.Count) * sizeof(Button)); _thumbsticks = pool.Rent((_thumbstickCount = srcThumbsticks.Count) * sizeof(Thumbstick)); _triggers = pool.Rent((_triggerCount = srcTriggers.Count) * sizeof(Trigger)); var dstButtons = GetButtons(); var dstThumbsticks = GetThumbsticks(); var dstTriggers = GetTriggers(); for (var i = 0; i < _buttonCount; i++) { dstButtons[i] = srcButtons[i]; } for (var i = 0; i < _thumbstickCount; i++) { dstThumbsticks[i] = srcThumbsticks[i]; } for (var i = 0; i < _triggerCount; i++) { dstTriggers[i] = srcTriggers[i]; } Deadzone = gamepad.Deadzone; }
internal unsafe JoystickState(IJoystick joystick, MemoryPool <byte> pool) { Name = joystick.Name; Index = joystick.Index; IsConnected = joystick.IsConnected; var srcAxes = joystick.Axes; var srcButtons = joystick.Buttons; var srcHats = joystick.Hats; _axes = pool.Rent((_axisCount = srcAxes.Count) * sizeof(Axis)); _buttons = pool.Rent((_buttonCount = srcButtons.Count) * sizeof(Button)); _hats = pool.Rent((_hatCount = srcHats.Count) * sizeof(Hat)); var dstAxes = GetAxes(); var dstButtons = GetButtons(); var dstHats = GetHats(); for (var i = 0; i < _axisCount; i++) { dstAxes[i] = srcAxes[i]; } for (var i = 0; i < _buttonCount; i++) { dstButtons[i] = srcButtons[i]; } for (var i = 0; i < _hatCount; i++) { dstHats[i] = srcHats[i]; } Deadzone = joystick.Deadzone; }
/// <summary> /// Compares the bytes in two streams for equality. /// </summary> /// <param name="left"><see cref="Stream"/> to compare.</param> /// <param name="right"><see cref="Stream"/> to compare.</param> /// <returns>TRUE if all bytes are equal in value, FALSE otherwise.</returns> public static async Task <bool> EqualsAsync(Stream left, Stream right) { const int wantedBuffersize = InternalUtils.StreamBufferSize; MemoryPool <byte> pool = MemoryPool <byte> .Shared; IMemoryOwner <byte> leftOwner = pool.Rent(wantedBuffersize); IMemoryOwner <byte> rightOwner = pool.Rent(wantedBuffersize); Memory <byte> leftBuffer = leftOwner.Memory; Memory <byte> rightBuffer = rightOwner.Memory; try { int leftRead; while ((leftRead = await left.ReadAsync(leftBuffer)) > 0) { int rightRead = await right.ReadAsync(rightBuffer); if (leftRead != rightRead) { return(false); } if (!Equals(leftBuffer.Span, rightBuffer.Span)) { return(false); } } return(true); } finally { leftOwner.Dispose(); rightOwner.Dispose(); } }
private void Ensure(int i) { var length = _memory.Length; if (length == 0) { var chunk = _pool.Rent(i); _owned = chunk; _memory = chunk.Memory; return; } var required = _next + i; if (required < length) { return; } while (required >= length) { length *= 2; } var newChunk = _pool.Rent(length); _memory.CopyTo(newChunk.Memory); _owned.Dispose(); _owned = newChunk; _memory = newChunk.Memory; }
public async Task SendCommand(Command command) { var line = $"{command.Id} {command.Name} {command.Text}\n"; if (line.Length > MaxCommandLength) { throw new InvalidOperationException("The command was too long."); } //log.Info("Sending '{command}'..", line); using (var buffer = Buffers.Rent(line.Length)) { var byteLength = Encoding.ASCII.GetBytes(line, buffer.Memory.Span); if (byteLength != line.Length) { throw new InvalidOperationException("Go search for a bug!"); } var dataToSend = buffer.Memory.Slice(0, byteLength); while (!dataToSend.IsEmpty) { var bytesSent = await client.SendAsync(dataToSend, SocketFlags.None); if (bytesSent == 0) { throw new InvalidOperationException("0 bytes sent"); } dataToSend = dataToSend.Slice(bytesSent); } } }
public static async Task WriteFromBase64Urlsafe( this Stream stream, PipeReader base64Pipe, CancellationToken cancelToken = default) { if (stream is null) { throw new ArgumentNullException(nameof(stream)); } if (base64Pipe is null) { throw new ArgumentNullException(nameof(base64Pipe)); } try { using (var base64Buffer = bytesPool.Rent()) { Memory <byte> base64Memory = base64Buffer.Memory; int base64Remaining = 0; while (true) { ReadResult readResult = await base64Pipe .ReadAsync(cancelToken) .ConfigureAwait(false); (base64Remaining, _) = await stream .WritePartialFromBase64Urlsafe(readResult.Buffer, base64Memory, base64Remaining, cancelToken) .ConfigureAwait(false); base64Pipe.AdvanceTo(readResult.Buffer.End); if (readResult.IsCompleted) { break; } } base64Memory = base64Memory.Slice(0, base64Remaining); await stream.WriteFinalFromBase64Urlsafe(base64Memory, cancelToken) .ConfigureAwait(false); } await stream.FlushAsync(cancelToken).ConfigureAwait(false); base64Pipe.Complete(); } catch (Exception e) { base64Pipe.Complete(e); throw; } }
public static void MemoryPool_byte_WrapSlice_start_noop() { MemoryPool <byte> pool = MemoryPool <byte> .Shared; IMemoryOwner <byte> owner1 = pool.Rent(99); IMemoryOwner <byte> owner2 = owner1.Slice(10); Assert.False(ReferenceEquals(owner1, owner2)); IMemoryOwner <byte> owner3 = pool.Rent(0); IMemoryOwner <byte> owner4 = owner3.Slice(0); Assert.True(ReferenceEquals(owner3, owner4)); }
private void AllocateReadTail() { if (_readHead == null) { Debug.Assert(_readTail == null); _readHead = CreateBufferSegment(); _readHead.SetMemory(_pool.Rent(GetSegmentSize())); _readTail = _readHead; } else if (_readTail.WritableBytes < _minimumReadThreshold) { CreateNewTailSegment(); } }
internal unsafe MouseState(IMouse mouse, MemoryPool <byte> pool) { // Set properties Name = mouse.Name; Index = mouse.Index; IsConnected = mouse.IsConnected; // Initial rentals var srcButtons = mouse.SupportedButtons; // get the source's supported buttons _buttonCount = srcButtons.Count; // assign the button count _buttons = pool.Rent(_buttonCount * sizeof(MouseButton)); // do a full rental of all supported buttons // we don't know how many buttons are pressed, do a full rental _pressedButtons = pool.Rent(_buttonCount * sizeof(MouseButton)); _pressedButtonCount = _buttonCount; // set the pressed button count to span the entire initial rental var buttons = GetSupportedButtons(); // get the span over the supported buttons var pressedButtons = GetPressedButtons(); // get the full span of the initial rental of the pressed buttons _pressedButtonCount = 0; // set the pressed button count to zero to actually count how many are pressed for (var i = 0; i < _buttonCount; i++) { buttons[i] = srcButtons[i]; if (mouse.IsButtonPressed(buttons[i])) { pressedButtons[_pressedButtonCount++] = buttons[i]; } } // Trim the pressed button rental using var wip = _pressedButtons; // get the original rental, and dispose of it when we're done var wipSpan = GetPressedButtons(); // get the trimmed span over the full initial rental _pressedButtons = pool.Rent(_pressedButtonCount * sizeof(MouseButton)); // create the trimmed rental pressedButtons = GetPressedButtons(); // get the span over the trimmed rental wipSpan.CopyTo(pressedButtons); // copy the trimmed span over the full rental to the trimmed rental // Scroll wheels var srcWheels = mouse.ScrollWheels; _scrollWheelCount = srcWheels.Count; _scrollWheels = pool.Rent(_scrollWheelCount * sizeof(ScrollWheel)); var dstWheels = GetScrollWheels(); for (var i = 0; i < _scrollWheelCount; i++) { dstWheels[i] = srcWheels[i]; } Position = mouse.Position; }
public static uint ToUInt24(ReadOnlySpan <byte> buffer, bool littleEndian = false) { using (var owner = _memoryPool.Rent(4)) { var memory = owner.Memory.Slice(0, 4); memory.Span.Clear(); buffer.CopyTo(memory.Span.Slice(1)); if (!littleEndian) { memory.Span.Reverse(); } return(BitConverter.ToUInt32(memory.Span)); } }
protected unsafe override void Deserialize( ReadOnlySpan <byte> span, MemoryPool <byte> memoryPool, out ReadOnlyMemory <byte> memory, out IMemoryOwner <byte> owner, out PublicKeyBytes publicKeyBytes) { if (Unsafe.SizeOf <PublicKeyBytes>() != crypto_sign_ed25519_PUBLICKEYBYTES) { throw Error.InvalidOperation_InternalError(); } Debug.Assert(span.Length == crypto_sign_ed25519_SEEDBYTES); owner = memoryPool.Rent(crypto_sign_ed25519_SECRETKEYBYTES); memory = owner.Memory.Slice(0, crypto_sign_ed25519_SECRETKEYBYTES); fixed(PublicKeyBytes *pk = &publicKeyBytes) fixed(byte *sk = owner.Memory.Span) fixed(byte *seed_ = span) { int error = crypto_sign_ed25519_seed_keypair(pk, sk, seed_); Debug.Assert(error == 0); } }
private void AddToPushback(ReadOnlySpan <char> c) { if (!PushBackOwner.HasValue) { PushBackOwner.Value = MemoryPool.Rent(BufferSizeHint); } var pushBackOwnerValue = PushBackOwner.Value; if (PushBackLength + c.Length > pushBackOwnerValue.Memory.Length) { var oldSize = pushBackOwnerValue.Memory.Length; var newSize = (PushBackLength + c.Length) * 2; // double size, because we're sharing the buffer var newOwner = Utils.RentMustIncrease(MemoryPool, newSize, oldSize); pushBackOwnerValue.Memory.CopyTo(newOwner.Memory); pushBackOwnerValue.Dispose(); PushBackOwner.Value = pushBackOwnerValue = newOwner; } if (PushBackLength + c.Length > pushBackOwnerValue.Memory.Length) { Throw.InvalidOperationException($"Could not allocate large enough buffer to read headers"); } c.CopyTo(PushBack.Span.Slice(PushBackLength)); PushBackLength += c.Length; }
public static void MemoryPoolPinOffsetAtEnd() { MemoryPool <int> pool = MemoryPool <int> .Shared; OwnedMemory <int> block = pool.Rent(10); Span <int> sp = block.Span; Assert.Equal(block.Length, sp.Length); int byteOffset = 0; try { byteOffset = checked (block.Length * sizeof(int)); } catch (OverflowException) { return; // The pool gave us a very large block - too big to compute the byteOffset needed to carry out this test. Skip. } using (MemoryHandle newMemoryHandle = block.Pin(byteOffset: byteOffset)) { unsafe { void *pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(sp)); Assert.Equal((IntPtr)pSpan, ((IntPtr)newMemoryHandle.Pointer) - byteOffset); } } }
internal BufferWithPushback(MemoryPool <char> memoryPool, int initialBufferSize) { MemoryPool = memoryPool; BackingOwner = MemoryPool.Rent(initialBufferSize); UpdateBufferAndPushBack(); }
public static async IAsyncEnumerator <string> ReadTextMessages(this WebSocket socket, MemoryPool <byte> memoryPool, int minBufferSize, CancellationToken cancellationToken) { if (socket == null) { throw new ArgumentNullException(nameof(socket)); } if (memoryPool == null) { throw new ArgumentNullException(nameof(memoryPool)); } while (true) { ValueWebSocketReceiveResult result; using var buffer = memoryPool.Rent(minBufferSize); using var ms = new MemoryStream(buffer.Memory.Length); do { result = await socket.ReceiveAsync(buffer.Memory, cancellationToken); #pragma warning disable IDE0010 // Add missing cases (all are covered) switch (result.MessageType) #pragma warning restore IDE0010 // Add missing cases { case WebSocketMessageType.Close: yield break; case var type and not WebSocketMessageType.Text: throw new NotSupportedException($"Invalid message type received: {type}"); } ms.Write(buffer.Memory.Span[..result.Count]);
private async ValueTask <LTrieNodeExternalLinkStruct> GetRemainingExternalLink(LTrieNodeStruct gn, byte value) { IMemoryOwner <byte>?owner = null; var restLength = gn.GetRestLength(); var secondLinkPointer = gn.GetSecondExternalLinkOwnPointer(); if (!Storage.TryDirectRead(secondLinkPointer, restLength, out var memory)) { owner = MemoryPool.Rent(restLength); var outputMemory = owner.Memory.Slice(0, restLength); await Storage.Read(secondLinkPointer, outputMemory); memory = outputMemory; } for (int linkIndex = 0; linkIndex < gn.ExternalLinkSlotCount - 1; linkIndex++) { var linkOwnPointer = secondLinkPointer + linkIndex * Sizes.ExternalLinkLength; var l = new LTrieNodeExternalLinkStruct(linkOwnPointer, memory.Span.Slice(linkIndex * Sizes.ExternalLinkLength, Sizes.ExternalLinkLength)); if (l.Pointer != 0 && l.Value == value) { owner?.Dispose(); return(l); } } owner?.Dispose(); return(default);
internal override unsafe void CreateKey( ReadOnlySpan <byte> seed, MemoryPool <byte> memoryPool, out ReadOnlyMemory <byte> memory, out IMemoryOwner <byte> owner, out PublicKey?publicKey) { if (Unsafe.SizeOf <PublicKeyBytes>() != crypto_sign_ed25519_PUBLICKEYBYTES) { throw Error.InvalidOperation_InternalError(); } Debug.Assert(seed.Length == crypto_sign_ed25519_SEEDBYTES); publicKey = new PublicKey(this); owner = memoryPool.Rent(crypto_sign_ed25519_SECRETKEYBYTES); memory = owner.Memory.Slice(0, crypto_sign_ed25519_SECRETKEYBYTES); fixed(PublicKeyBytes *pk = publicKey) fixed(byte *sk = owner.Memory.Span) fixed(byte *seed_ = seed) { int error = crypto_sign_ed25519_seed_keypair(pk, sk, seed_); Debug.Assert(error == 0); } }
public async Task UsageWithLifeAsync(int size) { using (var array = _memPool.Rent(size)) { await DoSomethingAsync(array.Memory); } }
// To be used by HttpSys internal NativeRequestContext(SafeNativeOverlapped nativeOverlapped, MemoryPool <Byte> memoryPool, uint?bufferSize, ulong requestId) { _nativeOverlapped = nativeOverlapped; // TODO: // Apparently the HttpReceiveHttpRequest memory alignment requirements for non - ARM processors // are different than for ARM processors. We have seen 4 - byte - aligned buffers allocated on // virtual x64/x86 machines which were accepted by HttpReceiveHttpRequest without errors. In // these cases the buffer alignment may cause reading values at invalid offset. Setting buffer // alignment to 0 for now. // // _bufferAlignment = (int)(requestAddress.ToInt64() & 0x07); _bufferAlignment = 0; var newSize = (int)(bufferSize ?? DefaultBufferSize) + AlignmentPadding; if (newSize <= memoryPool.MaxBufferSize) { _backingBuffer = memoryPool.Rent(newSize); } else { // No size limit _backingBuffer = MemoryPool <byte> .Shared.Rent(newSize); } _backingBuffer.Memory.Span.Fill(0);// Zero the buffer _memoryHandle = _backingBuffer.Memory.Pin(); _nativeRequest = (HttpApiTypes.HTTP_REQUEST *)((long)_memoryHandle.Pointer + _bufferAlignment); RequestId = requestId; }
public void MemoryPoolBlockReferenceTests() { var pool = new MemoryPool(); BufferReferenceTests.TestOwnedBuffer(() => pool.Rent(1024), block => pool.Return((MemoryPoolBlock)block)); pool.Dispose(); }
/// <summary> /// GetNext supporting memory pools /// </summary> /// <param name="pool">Memory pool</param> /// <param name="entry">Copy of entry, if found</param> /// <param name="entryLength">Actual length of entry</param> /// <param name="currentAddress">Logical address of entry</param> /// <param name="nextAddress">Logical address of next entry</param> /// <returns></returns> public unsafe bool GetNext(MemoryPool <byte> pool, out IMemoryOwner <byte> entry, out int entryLength, out long currentAddress, out long nextAddress) { if (disposed) { entry = default; entryLength = default; currentAddress = default; nextAddress = default; return(false); } epoch.Resume(); if (GetNextInternal(out long physicalAddress, out entryLength, out currentAddress, out nextAddress)) { entry = pool.Rent(entryLength); fixed(byte *bp = &entry.Memory.Span.GetPinnableReference()) Buffer.MemoryCopy((void *)(headerSize + physicalAddress), bp, entryLength, entryLength); epoch.Suspend(); return(true); } entry = default; entryLength = default; epoch.Suspend(); return(false); }
internal override unsafe void CreateKey( ReadOnlySpan <byte> seed, MemoryPool <byte> memoryPool, out ReadOnlyMemory <byte> memory, out IMemoryOwner <byte> owner, out PublicKey?publicKey) { if (Unsafe.SizeOf <PublicKeyBytes>() != crypto_scalarmult_curve25519_SCALARBYTES) { throw Error.InvalidOperation_InternalError(); } Debug.Assert(seed.Length == crypto_scalarmult_curve25519_SCALARBYTES); publicKey = new PublicKey(this); owner = memoryPool.Rent(crypto_scalarmult_curve25519_SCALARBYTES); memory = owner.Memory.Slice(0, crypto_scalarmult_curve25519_SCALARBYTES); seed.CopyTo(owner.Memory.Span); fixed(PublicKeyBytes *q = publicKey) fixed(byte *n = owner.Memory.Span) { int error = crypto_scalarmult_curve25519_base(q, n); Debug.Assert(error == 0); Debug.Assert((((byte *)q)[crypto_scalarmult_curve25519_SCALARBYTES - 1] & 0x80) == 0); } }
private bool AssembleMessage(RtmpMessageEntry messageEntry, RtmpChunk chunk, out RtmpMessage message) { message = null; var currentMessage = messageEntry.Message; if (currentMessage == null) { var payload = _memoryPool.Rent(chunk.Message.Length); currentMessage = new RtmpMessage(chunk.Header, chunk.Message, payload); messageEntry.Message = currentMessage; } var memory = currentMessage.Payload.Slice(messageEntry.BytesRead, chunk.PayloadLength); var reader = new SequenceReader <byte>(chunk.Payload); reader.TryCopyTo(memory.Span); messageEntry.BytesRead += chunk.PayloadLength; // if message is complete .. return it. if (messageEntry.BytesRemaining == 0) { message = messageEntry.Message; _logger.LogInformation($"Parsed message :{message.Header}: Message: {message.Message}"); messageEntry.BytesRead = 0; messageEntry.Message = null; return(true); } return(false); }
internal RequiredSet(MemoryPool <char> pool, int numMembers) { var neededChars = (numMembers / BITS_PER_CHAR); if ((numMembers % BITS_PER_CHAR > 0)) { neededChars++; } var space = neededChars * 2; Owner = pool.Rent(space); Owner.Memory.Span.Slice(0, space).Clear(); Required = Owner.Memory.Slice(0, neededChars); Set = Owner.Memory.Slice(neededChars, neededChars); LongsInLength = neededChars / CHARS_PER_LONG; var leftOver = neededChars % CHARS_PER_LONG; if (leftOver >= CHARS_PER_INT) { HasIntInLength = true; leftOver -= CHARS_PER_INT; } else { HasIntInLength = false; } HasCharInLength = leftOver != 0; }
/// <summary> /// Convert payload to specified (disposable) memory owner /// </summary> public (IMemoryOwner <byte> memory, int length) ToMemoryOwner(MemoryPool <byte> pool) { var dst = pool.Rent(Length); AsReadOnlySpan().CopyTo(dst.Memory.Span); return(dst, Length); }
public void UsageWithLife(int size) { using (var array = _memPool.Rent(size)) { DoSomething(array.Memory); } }
internal async ValueTask <LTrieValue> ReadValue(long pointer) { //1byte - protocol, FullKeyLen (2 bytes), FullValueLen (4 bytes),[Reserved Space For Update- 4 bytes],FullKey,FullValue //1 + 2 + 4 + 4 + 100 = 111 int readLen = 256; var owner = MemoryPool.Rent(readLen); var memory = owner.Memory.Slice(0, readLen); await Storage.Read(pointer, memory); var protocol = memory.Span[0]; var headerSize = protocol == 0 ? 7 : 11; ushort keySize = memory.ToReadOnly().Span.Slice(1).ReadUInt16BigEndian(); if (keySize > (readLen - headerSize)) { readLen = keySize + headerSize; owner.Dispose(); owner = MemoryPool.Rent(readLen); memory = owner.Memory.Slice(0, readLen); await Storage.Read(pointer, memory); } bool nullValue = (memory.Span[3] & 0x80) != 0; int valueSize = (int)(nullValue ? 0U : memory.ToReadOnly().Span.Slice(3).ReadUInt32BigEndian()); return(new LTrieValue(this, owner.Slice(headerSize, keySize), valueSize) { Protocol = protocol, Pointer = pointer, ValuePointer = pointer + headerSize + keySize, ValueMaxLength = protocol == 0 ? valueSize : (int)memory.Slice(7).ToReadOnly().Span.ReadUInt32BigEndian() }); }
internal Partition(DirectoryInfo location, int bufferSize, int recordsPerPartition, long partitionNumber, MemoryPool <LogEntryMetadata>?cachePool, int readersCount) : base(Path.Combine(location.FullName, partitionNumber.ToString(InvariantCulture)), bufferSize, readersCount, FileOptions.RandomAccess | FileOptions.WriteThrough | FileOptions.Asynchronous) { Capacity = recordsPerPartition; FirstIndex = partitionNumber * recordsPerPartition; lookupCache = cachePool?.Rent(recordsPerPartition); }
/// <summary> /// Copy to given SpanByteAndMemory (header length and payload copied to actual span/memory) /// </summary> /// <param name="src"></param> /// <param name="dst"></param> /// <param name="memoryPool"></param> private unsafe void CopyWithHeaderTo(ref SpanByte src, ref SpanByteAndMemory dst, MemoryPool <byte> memoryPool) { if (dst.IsSpanByte) { if (dst.Length >= src.TotalSize) { dst.Length = src.TotalSize; var span = dst.SpanByte.AsSpan(); fixed(byte *ptr = span) * (int *)ptr = src.Length; src.AsReadOnlySpan().CopyTo(span.Slice(sizeof(int))); return; } dst.ConvertToHeap(); } dst.Length = src.TotalSize; dst.Memory = memoryPool.Rent(src.TotalSize); dst.Length = src.TotalSize; fixed(byte *ptr = dst.Memory.Memory.Span) * (int *)ptr = src.Length; src.AsReadOnlySpan().CopyTo(dst.Memory.Memory.Span.Slice(sizeof(int))); }
/// <summary> /// Copy to given SpanByteAndMemory (header and payload copied to actual span/memory) /// </summary> /// <param name="dst"></param> /// <param name="memoryPool"></param> public void CopyWithHeaderTo(ref SpanByteAndMemory dst, MemoryPool <byte> memoryPool) { if (dst.IsSpanByte) { if (dst.Length >= TotalSize) { dst.Length = TotalSize; var span = dst.SpanByte.AsSpan(); fixed(byte *ptr = span) * (int *)ptr = Length; dst.SpanByte.ExtraMetadata = ExtraMetadata; AsReadOnlySpan().CopyTo(span.Slice(sizeof(int) + MetadataSize)); return; } dst.ConvertToHeap(); } dst.Memory = memoryPool.Rent(TotalSize); dst.Length = TotalSize; fixed(byte *ptr = dst.Memory.Memory.Span) * (int *)ptr = Length; dst.SpanByte.ExtraMetadata = ExtraMetadata; AsReadOnlySpan().CopyTo(dst.Memory.Memory.Span.Slice(sizeof(int) + MetadataSize)); }