internal uv_buf_t GetBuffer(IByteBuffer buf) { Debug.Assert(!_pin.IsAllocated); // Do not pin the buffer again if it is already pinned IntPtr arrayHandle = IntPtr.Zero; if (buf.HasMemoryAddress) { arrayHandle = buf.AddressOfPinnedMemory(); } int index = buf.WriterIndex; if (arrayHandle == IntPtr.Zero) { _pin = GCHandle.Alloc(buf.Array, GCHandleType.Pinned); arrayHandle = _pin.AddrOfPinnedObject(); index += buf.ArrayOffset; } int length = buf.WritableBytes; _buffer = buf; return(new uv_buf_t(arrayHandle + index, length)); }
internal static void SetBytes(AbstractByteBuffer buf, byte *addr, int index, IByteBuffer src, int srcIndex, int length) { if (MathUtil.IsOutOfBounds(srcIndex, length, src.Capacity)) { throw new IndexOutOfRangeException($"srcIndex: {srcIndex}"); } if (length != 0) { if (src.HasMemoryAddress) { IntPtr ptr = src.AddressOfPinnedMemory(); if (ptr != IntPtr.Zero) { PlatformDependent.CopyMemory((byte *)(ptr + srcIndex), addr, length); } else { fixed(byte *source = &src.GetPinnableMemoryAddress()) { PlatformDependent.CopyMemory(source + srcIndex, addr, length); } } } else if (src.HasArray) { PlatformDependent.CopyMemory(src.Array, src.ArrayOffset + srcIndex, addr, length); } else { src.GetBytes(srcIndex, buf, index, length); } } }
internal static IByteBuffer Copy(AbstractByteBuffer buf, byte *addr, int index, int length) { IByteBuffer copy = buf.Allocator.DirectBuffer(length, buf.MaxCapacity); if (length != 0) { if (copy.HasMemoryAddress) { IntPtr ptr = copy.AddressOfPinnedMemory(); if (ptr != IntPtr.Zero) { PlatformDependent.CopyMemory(addr, (byte *)ptr, length); } else { fixed(byte *dst = ©.GetPinnableMemoryAddress()) { PlatformDependent.CopyMemory(addr, dst, length); } } copy.SetIndex(0, length); } else { copy.WriteBytes(buf, index, length); } } return(copy); }
internal static void GetBytes(AbstractByteBuffer buf, byte *addr, int index, IByteBuffer dst, int dstIndex, int length) { if (MathUtil.IsOutOfBounds(dstIndex, length, dst.Capacity)) { throw new IndexOutOfRangeException($"dstIndex: {dstIndex}"); } if (dst.HasMemoryAddress) { IntPtr ptr = dst.AddressOfPinnedMemory(); if (ptr != IntPtr.Zero) { PlatformDependent.CopyMemory(addr, (byte *)(ptr + dstIndex), length); } else { fixed(byte *destination = &dst.GetPinnableMemoryAddress()) { PlatformDependent.CopyMemory(addr, destination + dstIndex, length); } } } else if (dst.HasArray) { PlatformDependent.CopyMemory(addr, dst.Array, dst.ArrayOffset + dstIndex, length); } else { dst.SetBytes(dstIndex, buf, index, length); } }
internal static void SetBytes(AbstractByteBuffer buf, byte *addr, int index, IByteBuffer src, int srcIndex, int length) { //if (src is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.src); } //if (MathUtil.IsOutOfBounds(srcIndex, length, src.Capacity)) //{ // ThrowHelper.ThrowIndexOutOfRangeException_SrcIndex(srcIndex); //} if (0u >= (uint)length) { return; } if (src.HasMemoryAddress) { IntPtr ptr = src.AddressOfPinnedMemory(); if (ptr != IntPtr.Zero) { PlatformDependent.CopyMemory((byte *)(ptr + srcIndex), addr, length); } else { fixed(byte *source = &src.GetPinnableMemoryAddress()) { PlatformDependent.CopyMemory(source + srcIndex, addr, length); } } return; } SetBytes0(buf, addr, index, src, srcIndex, length); }
//internal static int SetBytes(AbstractByteBuffer buf, byte* addr, int index, Stream input, int length) //{ // IByteBuffer tmpBuf = buf.Allocator.HeapBuffer(length); // try // { // int readTotal = 0; // int readBytes; // byte[] tmp = tmpBuf.Array; // int offset = tmpBuf.ArrayOffset; // do // { // readBytes = input.Read(tmp, offset + readTotal, length - readTotal); // readTotal += readBytes; // } // while (readBytes > 0 && readTotal < length); // //if (readTotal > 0) // //{ // PlatformDependent.CopyMemory(tmp, offset, addr, readTotal); // //} // return readTotal; // } // finally // { // tmpBuf.Release(); // } //} internal static void GetBytes(AbstractByteBuffer buf, byte *addr, int index, IByteBuffer dst, int dstIndex, int length) { //if (dst is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dst); } //if (MathUtil.IsOutOfBounds(dstIndex, length, dst.Capacity)) //{ // ThrowHelper.ThrowIndexOutOfRangeException_DstIndex(dstIndex); //} if (0u >= (uint)length) { return; } if (dst.HasMemoryAddress) { IntPtr ptr = dst.AddressOfPinnedMemory(); if (ptr != IntPtr.Zero) { PlatformDependent.CopyMemory(addr, (byte *)(ptr + dstIndex), length); } else { fixed(byte *destination = &dst.GetPinnableMemoryAddress()) { PlatformDependent.CopyMemory(addr, destination + dstIndex, length); } } return; } GetBytes0(buf, addr, index, dst, dstIndex, length); }
public void TestHasArrayWhenEmptyAndIsDirect() { IByteBuffer buf = NewBuffer(new IByteBuffer[0]); Assert.True(buf.HasArray); Assert.Equal(Unpooled.Empty.Array, buf.Array); Assert.Equal(Unpooled.Empty.IsDirect, buf.IsDirect); Assert.Equal(Unpooled.Empty.AddressOfPinnedMemory(), buf.AddressOfPinnedMemory()); buf.Release(); }
public IntPtr AddressOfPinnedMemory() => Buf.AddressOfPinnedMemory();
bool Add(IByteBuffer buf) { if (this.count == MaximumLimit) { return(false); } int len = buf.ReadableBytes; if (len == 0) { return(true); } if (this.maxBytes - len < this.size && this.count > 0) { return(false); } IntPtr addr = IntPtr.Zero; if (buf.HasMemoryAddress) { addr = buf.AddressOfPinnedMemory(); } if (addr != IntPtr.Zero) { this.Add(addr, buf.ReaderIndex, len); } else { int bufferCount = buf.IoBufferCount; if (MaximumLimit - bufferCount < this.count) { return(false); } if (bufferCount == 1) { ArraySegment <byte> arraySegment = buf.GetIoBuffer(); byte[] array = arraySegment.Array; GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); this.handles.Add(handle); addr = handle.AddrOfPinnedObject(); this.Add(addr, arraySegment.Offset, arraySegment.Count); } else { ArraySegment <byte>[] segments = buf.GetIoBuffers(); for (int i = 0; i < segments.Length; i++) { GCHandle handle = GCHandle.Alloc(segments[i].Array, GCHandleType.Pinned); this.handles.Add(handle); addr = handle.AddrOfPinnedObject(); this.Add(addr, segments[i].Offset, segments[i].Count); } } } return(true); }
internal void Prepare() { IByteBuffer byteBuffer = this.buffer; int index = byteBuffer.ReaderIndex; int length = byteBuffer.ReadableBytes; IntPtr addr = byteBuffer.AddressOfPinnedMemory(); if (addr != IntPtr.Zero) { this.bufs[0] = new uv_buf_t(addr + index, length); this.size = 1; return; } if (byteBuffer.HasArray) { byte[] array = byteBuffer.Array; GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); this.handles.Add(handle); addr = handle.AddrOfPinnedObject(); this.bufs[0] = new uv_buf_t(addr + this.buffer.ArrayOffset + index, length); this.size = 1; return; } if (byteBuffer.IoBufferCount == 1) { ArraySegment <byte> arraySegment = byteBuffer.GetIoBuffer(index, length); byte[] array = arraySegment.Array; GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); this.handles.Add(handle); addr = handle.AddrOfPinnedObject(); this.bufs[0] = new uv_buf_t(addr + arraySegment.Offset, arraySegment.Count); this.size = 1; return; } ArraySegment <byte>[] segments = byteBuffer.GetIoBuffers(index, length); if (segments.Length > this.bufs.Length) { if (this.pin.IsAllocated) { this.pin.Free(); } this.bufs = new uv_buf_t[segments.Length]; this.pin = GCHandle.Alloc(this.bufs, GCHandleType.Pinned); } for (int i = 0; i < segments.Length; i++) { GCHandle handle = GCHandle.Alloc(segments[i].Array, GCHandleType.Pinned); this.handles.Add(handle); addr = handle.AddrOfPinnedObject(); this.bufs[i] = new uv_buf_t(addr + segments[i].Offset, segments[i].Count); } this.size = segments.Length; }