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
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; |
|
} |
|
}
|
|
|