diff options
Diffstat (limited to 'lib')
3 files changed, 69 insertions, 22 deletions
diff --git a/lib/Net.Http/src/Core/Response/ResponsBodyDataState.cs b/lib/Net.Http/src/Core/Response/ResponsBodyDataState.cs index 797d490..bd43def 100644 --- a/lib/Net.Http/src/Core/Response/ResponsBodyDataState.cs +++ b/lib/Net.Http/src/Core/Response/ResponsBodyDataState.cs @@ -3,10 +3,10 @@ * * Library: VNLib * Package: VNLib.Net.Http -* File: ResponseWriter.cs +* File: ResponsBodyDataState.cs * -* ResponseWriter.cs is part of VNLib.Net.Http which is part of the larger -* VNLib collection of libraries and utilities. +* ResponsBodyDataState.cs is part of VNLib.Net.Http which is part of +* the larger VNLib collection of libraries and utilities. * * VNLib.Net.Http is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as diff --git a/lib/Plugins.Essentials/src/Extensions/EssentialHttpEventExtensions.cs b/lib/Plugins.Essentials/src/Extensions/EssentialHttpEventExtensions.cs index 66155dd..0ca5b8f 100644 --- a/lib/Plugins.Essentials/src/Extensions/EssentialHttpEventExtensions.cs +++ b/lib/Plugins.Essentials/src/Extensions/EssentialHttpEventExtensions.cs @@ -796,6 +796,66 @@ namespace VNLib.Plugins.Essentials.Extensions //Parse the file using the specified parser return parser(file.FileData, file.ContentTypeString()); } + + /// <summary> + /// Reads the contents of an uploaded file at the desired intex into memory + /// and returns a managed byte array containing the file data + /// </summary> + /// <param name="ev"></param> + /// <param name="uploadIndex">The index of the uploaded file to buffer</param> + /// <returns>A value task that resolves the uploaded data</returns> + /// <exception cref="IOException"></exception> + public static ValueTask<byte[]> ReadFileDataAsync(this HttpEntity ev, int uploadIndex = 0) + { + ArgumentNullException.ThrowIfNull(ev); + + /* + * File should exist at the desired index and have a length greater than 0 + * otherwise return an empty buffer + */ + if (ev.Files.Count <= uploadIndex || ev.Files[uploadIndex].Length == 0) + { + return ValueTask.FromResult(Array.Empty<byte>()); + } + + return ReadFileDataAsync(ev, uploadIndex); + + static async ValueTask<byte[]> ReadFileDataAsync(HttpEntity entity, int fileIndex) + { + FileUpload upload = entity.Files[fileIndex]; + + /* + * Alloc an uninitialized buffer to read the file data into, it should ALL + * be overwritten during read operation + */ + byte[] buffer = GC.AllocateUninitializedArray<byte>((int)upload.Length); + + int read = 0; + + do + { + Memory<byte> mem = buffer.AsMemory(read, buffer.Length - read); + + int r = await upload.FileData.ReadAsync(mem, entity.EventCancellation); + + //If no data was read force break and deal with read data + if (r == 0) + { + break; + } + + read += r; + } while (read < buffer.Length); + + //Buffer is exact length, so read should be equal to length + if (read != buffer.Length) + { + throw new IOException("Failed to read entire file data, this may be an internal error"); + } + + return buffer; + } + } /// <summary> /// Get a <see cref="DirectoryInfo"/> instance that points to the current sites filesystem root. diff --git a/lib/Utils/src/Extensions/MemoryExtensions.cs b/lib/Utils/src/Extensions/MemoryExtensions.cs index 083c7cf..c433527 100644 --- a/lib/Utils/src/Extensions/MemoryExtensions.cs +++ b/lib/Utils/src/Extensions/MemoryExtensions.cs @@ -146,8 +146,13 @@ namespace VNLib.Utils.Extensions /// <exception cref="OutOfMemoryException"></exception> /// <exception cref="ObjectDisposedException"></exception> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static MemoryManager<T> DirectAlloc<T>(this IUnmangedHeap heap, nuint size, bool zero = false) where T : unmanaged + public static MemoryManager<T> DirectAlloc<T>(this IUnmangedHeap heap, int size, bool zero = false) where T : unmanaged { + /* + * Size it limited to int32 because the memory manager uses int32 for length + * and the constructor will attempt to cast the size to int32 or cause an + * overflow exception + */ MemoryHandle<T> handle = heap.Alloc<T>(size, zero); return new SysBufferMemoryManager<T>(handle, true); } @@ -177,24 +182,6 @@ namespace VNLib.Utils.Extensions //Method only exists for consistancy since unsafe handles are always 32bit [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetIntLength<T>(this in UnsafeMemoryHandle<T> handle) where T : unmanaged => handle.IntLength; - - /// <summary> - /// Allows direct allocation of a fixed size <see cref="MemoryManager{T}"/> from a <see cref="IUnmangedHeap"/> instance - /// of the specified number of elements - /// </summary> - /// <typeparam name="T">The unmanaged data type</typeparam> - /// <param name="heap"></param> - /// <param name="size">The number of elements to allocate on the heap</param> - /// <param name="zero">Optionally zeros conents of the block when allocated</param> - /// <returns>The <see cref="MemoryManager{T}"/> wrapper around the block of memory</returns> - /// <exception cref="OverflowException"></exception> - /// <exception cref="ArgumentOutOfRangeException"></exception> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static MemoryManager<T> DirectAlloc<T>(this IUnmangedHeap heap, nint size, bool zero = false) where T : unmanaged - { - ArgumentOutOfRangeException.ThrowIfNegative(size); - return DirectAlloc<T>(heap, (nuint)size, zero); - } /// <summary> /// Gets an offset pointer from the base postion to the number of bytes specified. Performs bounds checks |