Fork of mellinoe/ImGui.NET, an ImGui wrapper for .NET, which includes access to internal functions.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

120 lines
3.3 KiB

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace ImGuiNET
{
public class TextInputBuffer : IDisposable
{
private uint _length;
public IntPtr Buffer { get; private set; }
public uint Length
{
get
{
return _length;
}
set
{
if (value > int.MaxValue)
{
throw new ArgumentOutOfRangeException("Length cannot be greater that Int32.MaxValue.");
}
Resize((int)value);
}
}
public TextInputBuffer(int length)
{
if (length < 0)
{
throw new ArgumentOutOfRangeException(nameof(length));
}
CreateBuffer(length);
}
public TextInputBuffer(string initialText)
{
Buffer = Marshal.StringToHGlobalAnsi(initialText);
Length = (uint)initialText.Length;
}
private unsafe void Resize(int newSize)
{
IntPtr newBuffer = Marshal.AllocHGlobal(newSize);
Unsafe.CopyBlock(newBuffer.ToPointer(), Buffer.ToPointer(), Length);
Marshal.FreeHGlobal(Buffer);
Buffer = newBuffer;
_length = (uint)newSize;
}
private unsafe void CreateBuffer(int size)
{
Buffer = Marshal.AllocHGlobal(size);
Length = (uint)size;
ClearData();
}
public unsafe void ClearData()
{
byte* ptr = (byte*)Buffer.ToPointer();
for (int i = 0; i < Length; i++)
{
ptr[i] = 0;
}
}
public void Dispose()
{
if (Buffer != IntPtr.Zero)
{
FreeNativeBuffer();
}
}
private void FreeNativeBuffer()
{
Marshal.FreeHGlobal(Buffer);
Buffer = IntPtr.Zero;
_length = 0;
}
public string StringValue
{
get
{
return Marshal.PtrToStringAnsi(Buffer);
}
set
{
Debug.Assert(value != null);
if (value.Length > Length) // Doesn't fit into current buffer
{
FreeNativeBuffer();
Buffer = Marshal.StringToHGlobalAnsi(value);
_length = (uint)value.Length;
}
else // Fits in current buffer, just copy data in.
{
IntPtr tempNativeString = Marshal.StringToHGlobalAnsi(value);
uint bytesToCopy = (uint)Math.Min(Length, value.Length);
unsafe
{
Unsafe.CopyBlock(Buffer.ToPointer(), tempNativeString.ToPointer(), bytesToCopy);
byte* endOfData = (byte*)Buffer.ToPointer() + bytesToCopy;
uint bytesToClear = _length - bytesToCopy;
Unsafe.InitBlock(endOfData, 0, bytesToClear);
}
Marshal.FreeHGlobal(tempNativeString);
}
}
}
public override string ToString() => StringValue;
}
}