Don't allocate extra buffers in lua [Push|To]String
This commit is contained in:
parent
bfae8d0f1e
commit
b10f8969ac
|
@ -26,4 +26,8 @@
|
||||||
<Nullable>disable</Nullable>
|
<Nullable>disable</Nullable>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.Memory" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Runtime.CompilerServices;
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -184,7 +185,7 @@ namespace NLua.Native
|
||||||
internal delegate* unmanaged[Cdecl]<lua_State, charptr_t, size_t, charptr_t> lua_pushlstring;
|
internal delegate* unmanaged[Cdecl]<lua_State, charptr_t, size_t, charptr_t> lua_pushlstring;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public charptr_t PushLString(lua_State luaState, byte[] s, size_t len)
|
public charptr_t PushLString(lua_State luaState, ReadOnlySpan<byte> s, size_t len)
|
||||||
{
|
{
|
||||||
fixed (byte* _s = s)
|
fixed (byte* _s = s)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -355,7 +356,7 @@ namespace NLua.Native
|
||||||
/// Pushes binary buffer onto the stack (usually UTF encoded string) or any arbitraty binary data
|
/// Pushes binary buffer onto the stack (usually UTF encoded string) or any arbitraty binary data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="buffer"></param>
|
/// <param name="buffer"></param>
|
||||||
public void PushBuffer(byte[] buffer)
|
public void PushBuffer(ReadOnlySpan<byte> buffer)
|
||||||
{
|
{
|
||||||
if (buffer == null)
|
if (buffer == null)
|
||||||
{
|
{
|
||||||
|
@ -378,8 +379,11 @@ namespace NLua.Native
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer = Encoding.UTF8.GetBytes(value);
|
// could also use GetByteCount here, but why iterate twice when we're renting the memory anyway?
|
||||||
PushBuffer(buffer);
|
byte[] buffer = ArrayPool<byte>.Shared.Rent(Encoding.UTF8.GetMaxByteCount(value.Length));
|
||||||
|
int actualLength = Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, 0);
|
||||||
|
PushBuffer(buffer.AsSpan(0, actualLength));
|
||||||
|
ArrayPool<byte>.Shared.Return(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -556,13 +560,7 @@ namespace NLua.Native
|
||||||
public long ToInteger(int index)
|
public long ToInteger(int index)
|
||||||
=> NativeMethods.ToIntegerX(Handle, index, out _);
|
=> NativeMethods.ToIntegerX(Handle, index, out _);
|
||||||
|
|
||||||
/// <summary>
|
private IntPtr ToLString(int index, bool callMetamethod, out int stringLength)
|
||||||
/// Converts the Lua value at the given index to a byte array.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="index"></param>
|
|
||||||
/// <param name="callMetamethod">Calls __tostring field if present</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public byte[] ToBuffer(int index, bool callMetamethod = true)
|
|
||||||
{
|
{
|
||||||
UIntPtr len;
|
UIntPtr len;
|
||||||
IntPtr buff;
|
IntPtr buff;
|
||||||
|
@ -577,19 +575,26 @@ namespace NLua.Native
|
||||||
buff = NativeMethods.ToLString(Handle, index, out len);
|
buff = NativeMethods.ToLString(Handle, index, out len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buff == IntPtr.Zero)
|
stringLength = (int)len;
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var length = (int)len;
|
return buff;
|
||||||
if (length == 0)
|
}
|
||||||
{
|
|
||||||
return Array.Empty<byte>();
|
/// <summary>
|
||||||
}
|
/// Converts the Lua value at the given index to a byte array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <param name="callMetamethod">Calls __tostring field if present</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public byte[] ToBuffer(int index, bool callMetamethod = true)
|
||||||
|
{
|
||||||
|
IntPtr buffer = ToLString(index, callMetamethod, out int length);
|
||||||
|
|
||||||
|
if (buffer == IntPtr.Zero) return null;
|
||||||
|
if (length == 0) return Array.Empty<byte>();
|
||||||
|
|
||||||
var output = new byte[length];
|
var output = new byte[length];
|
||||||
Marshal.Copy(buff, output, 0, length);
|
Marshal.Copy(buffer, output, 0, length);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,8 +606,15 @@ namespace NLua.Native
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public string ToString(int index, bool callMetamethod = true)
|
public string ToString(int index, bool callMetamethod = true)
|
||||||
{
|
{
|
||||||
var buffer = ToBuffer(index, callMetamethod);
|
var buffer = ToLString(index, callMetamethod, out int length);
|
||||||
return buffer == null ? null : Encoding.UTF8.GetString(buffer);
|
|
||||||
|
if (buffer == IntPtr.Zero) return null;
|
||||||
|
if (length == 0) return "";
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
return Encoding.UTF8.GetString((byte*)buffer.ToPointer(), length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue