Add a 2048-byte limit to stack allocation for strings.

internals
Eric Mellino 5 years ago
parent 37e468dbe5
commit 7ac01b7689
  1. 27
      src/CodeGenerator/Program.cs
  2. 21
      src/ImGui.NET/Generated/GlyphRangesBuilder.gen.cs
  3. 126
      src/ImGui.NET/Generated/ImFontAtlas.gen.cs
  4. 8946
      src/ImGui.NET/Generated/ImGui.gen.cs
  5. 21
      src/ImGui.NET/Generated/ImGuiIO.gen.cs
  6. 21
      src/ImGui.NET/Generated/ImGuiInputTextCallbackData.gen.cs
  7. 21
      src/ImGui.NET/Generated/ImGuiPayload.gen.cs
  8. 21
      src/ImGui.NET/Generated/ImGuiTextBuffer.gen.cs
  9. 84
      src/ImGui.NET/Generated/ImGuiTextFilter.gen.cs
  10. 194
      src/ImGui.NET/ImGui.Manual.cs
  11. 22
      src/ImGui.NET/Util.cs

@ -618,24 +618,35 @@ namespace CodeGenerator
else
{
preCallLines.Add($"byte* {nativeArgName};");
preCallLines.Add($"int {correctedIdentifier}_byteCount = 0;");
if (!hasDefault)
{
preCallLines.Add($"if ({textToEncode} != null)");
preCallLines.Add("{");
}
preCallLines.Add($" int {correctedIdentifier}_byteCount = Encoding.UTF8.GetByteCount({textToEncode});");
preCallLines.Add($" byte* {nativeArgName}_stackBytes = stackalloc byte[{correctedIdentifier}_byteCount + 1];");
preCallLines.Add($" {nativeArgName} = {nativeArgName}_stackBytes;");
preCallLines.Add($" fixed (char* {correctedIdentifier}_ptr = {textToEncode})");
preCallLines.Add(" {");
preCallLines.Add($" int {nativeArgName}_offset = Encoding.UTF8.GetBytes({correctedIdentifier}_ptr, {textToEncode}.Length, {nativeArgName}, {correctedIdentifier}_byteCount);");
preCallLines.Add($" {nativeArgName}[{nativeArgName}_offset] = 0;");
preCallLines.Add(" }");
preCallLines.Add($" {correctedIdentifier}_byteCount = Encoding.UTF8.GetByteCount({textToEncode});");
preCallLines.Add($" if ({correctedIdentifier}_byteCount > Util.StackAllocationSizeLimit)");
preCallLines.Add($" {{");
preCallLines.Add($" {nativeArgName} = Util.Allocate({correctedIdentifier}_byteCount + 1);");
preCallLines.Add($" }}");
preCallLines.Add($" else");
preCallLines.Add($" {{");
preCallLines.Add($" byte* {nativeArgName}_stackBytes = stackalloc byte[{correctedIdentifier}_byteCount + 1];");
preCallLines.Add($" {nativeArgName} = {nativeArgName}_stackBytes;");
preCallLines.Add($" }}");
preCallLines.Add($" int {nativeArgName}_offset = Util.GetUtf8({textToEncode}, {nativeArgName}, {correctedIdentifier}_byteCount);");
preCallLines.Add($" {nativeArgName}[{nativeArgName}_offset] = 0;");
if (!hasDefault)
{
preCallLines.Add("}");
preCallLines.Add($"else {{ {nativeArgName} = null; }}");
}
postCallLines.Add($"if ({correctedIdentifier}_byteCount > Util.StackAllocationSizeLimit)");
postCallLines.Add($"{{");
postCallLines.Add($" Util.Free({nativeArgName});");
postCallLines.Add($"}}");
}
}
else if (tr.Type == "char* []")

@ -30,20 +30,29 @@ namespace ImGuiNET
public void AddText(string text)
{
byte* native_text;
int text_byteCount = 0;
if (text != null)
{
int text_byteCount = Encoding.UTF8.GetByteCount(text);
byte* native_text_stackBytes = stackalloc byte[text_byteCount + 1];
native_text = native_text_stackBytes;
fixed (char* text_ptr = text)
text_byteCount = Encoding.UTF8.GetByteCount(text);
if (text_byteCount > Util.StackAllocationSizeLimit)
{
int native_text_offset = Encoding.UTF8.GetBytes(text_ptr, text.Length, native_text, text_byteCount);
native_text[native_text_offset] = 0;
native_text = Util.Allocate(text_byteCount + 1);
}
else
{
byte* native_text_stackBytes = stackalloc byte[text_byteCount + 1];
native_text = native_text_stackBytes;
}
int native_text_offset = Util.GetUtf8(text, native_text, text_byteCount);
native_text[native_text_offset] = 0;
}
else { native_text = null; }
byte* native_text_end = null;
ImGuiNative.GlyphRangesBuilder_AddText(NativePtr, native_text, native_text_end);
if (text_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_text);
}
}
public void BuildRanges(out ImVector out_ranges)
{

@ -85,121 +85,175 @@ namespace ImGuiNET
public ImFontPtr AddFontFromFileTTF(string filename, float size_pixels)
{
byte* native_filename;
int filename_byteCount = 0;
if (filename != null)
{
int filename_byteCount = Encoding.UTF8.GetByteCount(filename);
byte* native_filename_stackBytes = stackalloc byte[filename_byteCount + 1];
native_filename = native_filename_stackBytes;
fixed (char* filename_ptr = filename)
filename_byteCount = Encoding.UTF8.GetByteCount(filename);
if (filename_byteCount > Util.StackAllocationSizeLimit)
{
int native_filename_offset = Encoding.UTF8.GetBytes(filename_ptr, filename.Length, native_filename, filename_byteCount);
native_filename[native_filename_offset] = 0;
native_filename = Util.Allocate(filename_byteCount + 1);
}
else
{
byte* native_filename_stackBytes = stackalloc byte[filename_byteCount + 1];
native_filename = native_filename_stackBytes;
}
int native_filename_offset = Util.GetUtf8(filename, native_filename, filename_byteCount);
native_filename[native_filename_offset] = 0;
}
else { native_filename = null; }
ImFontConfig* font_cfg = null;
ushort* glyph_ranges = null;
ImFont* ret = ImGuiNative.ImFontAtlas_AddFontFromFileTTF(NativePtr, native_filename, size_pixels, font_cfg, glyph_ranges);
if (filename_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_filename);
}
return new ImFontPtr(ret);
}
public ImFontPtr AddFontFromFileTTF(string filename, float size_pixels, ImFontConfigPtr font_cfg)
{
byte* native_filename;
int filename_byteCount = 0;
if (filename != null)
{
int filename_byteCount = Encoding.UTF8.GetByteCount(filename);
byte* native_filename_stackBytes = stackalloc byte[filename_byteCount + 1];
native_filename = native_filename_stackBytes;
fixed (char* filename_ptr = filename)
filename_byteCount = Encoding.UTF8.GetByteCount(filename);
if (filename_byteCount > Util.StackAllocationSizeLimit)
{
native_filename = Util.Allocate(filename_byteCount + 1);
}
else
{
int native_filename_offset = Encoding.UTF8.GetBytes(filename_ptr, filename.Length, native_filename, filename_byteCount);
native_filename[native_filename_offset] = 0;
byte* native_filename_stackBytes = stackalloc byte[filename_byteCount + 1];
native_filename = native_filename_stackBytes;
}
int native_filename_offset = Util.GetUtf8(filename, native_filename, filename_byteCount);
native_filename[native_filename_offset] = 0;
}
else { native_filename = null; }
ImFontConfig* native_font_cfg = font_cfg.NativePtr;
ushort* glyph_ranges = null;
ImFont* ret = ImGuiNative.ImFontAtlas_AddFontFromFileTTF(NativePtr, native_filename, size_pixels, native_font_cfg, glyph_ranges);
if (filename_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_filename);
}
return new ImFontPtr(ret);
}
public ImFontPtr AddFontFromFileTTF(string filename, float size_pixels, ImFontConfigPtr font_cfg, IntPtr glyph_ranges)
{
byte* native_filename;
int filename_byteCount = 0;
if (filename != null)
{
int filename_byteCount = Encoding.UTF8.GetByteCount(filename);
byte* native_filename_stackBytes = stackalloc byte[filename_byteCount + 1];
native_filename = native_filename_stackBytes;
fixed (char* filename_ptr = filename)
filename_byteCount = Encoding.UTF8.GetByteCount(filename);
if (filename_byteCount > Util.StackAllocationSizeLimit)
{
native_filename = Util.Allocate(filename_byteCount + 1);
}
else
{
int native_filename_offset = Encoding.UTF8.GetBytes(filename_ptr, filename.Length, native_filename, filename_byteCount);
native_filename[native_filename_offset] = 0;
byte* native_filename_stackBytes = stackalloc byte[filename_byteCount + 1];
native_filename = native_filename_stackBytes;
}
int native_filename_offset = Util.GetUtf8(filename, native_filename, filename_byteCount);
native_filename[native_filename_offset] = 0;
}
else { native_filename = null; }
ImFontConfig* native_font_cfg = font_cfg.NativePtr;
ushort* native_glyph_ranges = (ushort*)glyph_ranges.ToPointer();
ImFont* ret = ImGuiNative.ImFontAtlas_AddFontFromFileTTF(NativePtr, native_filename, size_pixels, native_font_cfg, native_glyph_ranges);
if (filename_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_filename);
}
return new ImFontPtr(ret);
}
public ImFontPtr AddFontFromMemoryCompressedBase85TTF(string compressed_font_data_base85, float size_pixels)
{
byte* native_compressed_font_data_base85;
int compressed_font_data_base85_byteCount = 0;
if (compressed_font_data_base85 != null)
{
int compressed_font_data_base85_byteCount = Encoding.UTF8.GetByteCount(compressed_font_data_base85);
byte* native_compressed_font_data_base85_stackBytes = stackalloc byte[compressed_font_data_base85_byteCount + 1];
native_compressed_font_data_base85 = native_compressed_font_data_base85_stackBytes;
fixed (char* compressed_font_data_base85_ptr = compressed_font_data_base85)
compressed_font_data_base85_byteCount = Encoding.UTF8.GetByteCount(compressed_font_data_base85);
if (compressed_font_data_base85_byteCount > Util.StackAllocationSizeLimit)
{
int native_compressed_font_data_base85_offset = Encoding.UTF8.GetBytes(compressed_font_data_base85_ptr, compressed_font_data_base85.Length, native_compressed_font_data_base85, compressed_font_data_base85_byteCount);
native_compressed_font_data_base85[native_compressed_font_data_base85_offset] = 0;
native_compressed_font_data_base85 = Util.Allocate(compressed_font_data_base85_byteCount + 1);
}
else
{
byte* native_compressed_font_data_base85_stackBytes = stackalloc byte[compressed_font_data_base85_byteCount + 1];
native_compressed_font_data_base85 = native_compressed_font_data_base85_stackBytes;
}
int native_compressed_font_data_base85_offset = Util.GetUtf8(compressed_font_data_base85, native_compressed_font_data_base85, compressed_font_data_base85_byteCount);
native_compressed_font_data_base85[native_compressed_font_data_base85_offset] = 0;
}
else { native_compressed_font_data_base85 = null; }
ImFontConfig* font_cfg = null;
ushort* glyph_ranges = null;
ImFont* ret = ImGuiNative.ImFontAtlas_AddFontFromMemoryCompressedBase85TTF(NativePtr, native_compressed_font_data_base85, size_pixels, font_cfg, glyph_ranges);
if (compressed_font_data_base85_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_compressed_font_data_base85);
}
return new ImFontPtr(ret);
}
public ImFontPtr AddFontFromMemoryCompressedBase85TTF(string compressed_font_data_base85, float size_pixels, ImFontConfigPtr font_cfg)
{
byte* native_compressed_font_data_base85;
int compressed_font_data_base85_byteCount = 0;
if (compressed_font_data_base85 != null)
{
int compressed_font_data_base85_byteCount = Encoding.UTF8.GetByteCount(compressed_font_data_base85);
byte* native_compressed_font_data_base85_stackBytes = stackalloc byte[compressed_font_data_base85_byteCount + 1];
native_compressed_font_data_base85 = native_compressed_font_data_base85_stackBytes;
fixed (char* compressed_font_data_base85_ptr = compressed_font_data_base85)
compressed_font_data_base85_byteCount = Encoding.UTF8.GetByteCount(compressed_font_data_base85);
if (compressed_font_data_base85_byteCount > Util.StackAllocationSizeLimit)
{
native_compressed_font_data_base85 = Util.Allocate(compressed_font_data_base85_byteCount + 1);
}
else
{
int native_compressed_font_data_base85_offset = Encoding.UTF8.GetBytes(compressed_font_data_base85_ptr, compressed_font_data_base85.Length, native_compressed_font_data_base85, compressed_font_data_base85_byteCount);
native_compressed_font_data_base85[native_compressed_font_data_base85_offset] = 0;
byte* native_compressed_font_data_base85_stackBytes = stackalloc byte[compressed_font_data_base85_byteCount + 1];
native_compressed_font_data_base85 = native_compressed_font_data_base85_stackBytes;
}
int native_compressed_font_data_base85_offset = Util.GetUtf8(compressed_font_data_base85, native_compressed_font_data_base85, compressed_font_data_base85_byteCount);
native_compressed_font_data_base85[native_compressed_font_data_base85_offset] = 0;
}
else { native_compressed_font_data_base85 = null; }
ImFontConfig* native_font_cfg = font_cfg.NativePtr;
ushort* glyph_ranges = null;
ImFont* ret = ImGuiNative.ImFontAtlas_AddFontFromMemoryCompressedBase85TTF(NativePtr, native_compressed_font_data_base85, size_pixels, native_font_cfg, glyph_ranges);
if (compressed_font_data_base85_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_compressed_font_data_base85);
}
return new ImFontPtr(ret);
}
public ImFontPtr AddFontFromMemoryCompressedBase85TTF(string compressed_font_data_base85, float size_pixels, ImFontConfigPtr font_cfg, IntPtr glyph_ranges)
{
byte* native_compressed_font_data_base85;
int compressed_font_data_base85_byteCount = 0;
if (compressed_font_data_base85 != null)
{
int compressed_font_data_base85_byteCount = Encoding.UTF8.GetByteCount(compressed_font_data_base85);
byte* native_compressed_font_data_base85_stackBytes = stackalloc byte[compressed_font_data_base85_byteCount + 1];
native_compressed_font_data_base85 = native_compressed_font_data_base85_stackBytes;
fixed (char* compressed_font_data_base85_ptr = compressed_font_data_base85)
compressed_font_data_base85_byteCount = Encoding.UTF8.GetByteCount(compressed_font_data_base85);
if (compressed_font_data_base85_byteCount > Util.StackAllocationSizeLimit)
{
native_compressed_font_data_base85 = Util.Allocate(compressed_font_data_base85_byteCount + 1);
}
else
{
int native_compressed_font_data_base85_offset = Encoding.UTF8.GetBytes(compressed_font_data_base85_ptr, compressed_font_data_base85.Length, native_compressed_font_data_base85, compressed_font_data_base85_byteCount);
native_compressed_font_data_base85[native_compressed_font_data_base85_offset] = 0;
byte* native_compressed_font_data_base85_stackBytes = stackalloc byte[compressed_font_data_base85_byteCount + 1];
native_compressed_font_data_base85 = native_compressed_font_data_base85_stackBytes;
}
int native_compressed_font_data_base85_offset = Util.GetUtf8(compressed_font_data_base85, native_compressed_font_data_base85, compressed_font_data_base85_byteCount);
native_compressed_font_data_base85[native_compressed_font_data_base85_offset] = 0;
}
else { native_compressed_font_data_base85 = null; }
ImFontConfig* native_font_cfg = font_cfg.NativePtr;
ushort* native_glyph_ranges = (ushort*)glyph_ranges.ToPointer();
ImFont* ret = ImGuiNative.ImFontAtlas_AddFontFromMemoryCompressedBase85TTF(NativePtr, native_compressed_font_data_base85, size_pixels, native_font_cfg, native_glyph_ranges);
if (compressed_font_data_base85_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_compressed_font_data_base85);
}
return new ImFontPtr(ret);
}
public ImFontPtr AddFontFromMemoryCompressedTTF(IntPtr compressed_font_data, int compressed_font_size, float size_pixels)

File diff suppressed because it is too large Load Diff

@ -173,19 +173,28 @@ namespace ImGuiNET
public void AddInputCharactersUTF8(string utf8_chars)
{
byte* native_utf8_chars;
int utf8_chars_byteCount = 0;
if (utf8_chars != null)
{
int utf8_chars_byteCount = Encoding.UTF8.GetByteCount(utf8_chars);
byte* native_utf8_chars_stackBytes = stackalloc byte[utf8_chars_byteCount + 1];
native_utf8_chars = native_utf8_chars_stackBytes;
fixed (char* utf8_chars_ptr = utf8_chars)
utf8_chars_byteCount = Encoding.UTF8.GetByteCount(utf8_chars);
if (utf8_chars_byteCount > Util.StackAllocationSizeLimit)
{
int native_utf8_chars_offset = Encoding.UTF8.GetBytes(utf8_chars_ptr, utf8_chars.Length, native_utf8_chars, utf8_chars_byteCount);
native_utf8_chars[native_utf8_chars_offset] = 0;
native_utf8_chars = Util.Allocate(utf8_chars_byteCount + 1);
}
else
{
byte* native_utf8_chars_stackBytes = stackalloc byte[utf8_chars_byteCount + 1];
native_utf8_chars = native_utf8_chars_stackBytes;
}
int native_utf8_chars_offset = Util.GetUtf8(utf8_chars, native_utf8_chars, utf8_chars_byteCount);
native_utf8_chars[native_utf8_chars_offset] = 0;
}
else { native_utf8_chars = null; }
ImGuiNative.ImGuiIO_AddInputCharactersUTF8(NativePtr, native_utf8_chars);
if (utf8_chars_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_utf8_chars);
}
}
public void ClearInputCharacters()
{

@ -52,20 +52,29 @@ namespace ImGuiNET
public void InsertChars(int pos, string text)
{
byte* native_text;
int text_byteCount = 0;
if (text != null)
{
int text_byteCount = Encoding.UTF8.GetByteCount(text);
byte* native_text_stackBytes = stackalloc byte[text_byteCount + 1];
native_text = native_text_stackBytes;
fixed (char* text_ptr = text)
text_byteCount = Encoding.UTF8.GetByteCount(text);
if (text_byteCount > Util.StackAllocationSizeLimit)
{
int native_text_offset = Encoding.UTF8.GetBytes(text_ptr, text.Length, native_text, text_byteCount);
native_text[native_text_offset] = 0;
native_text = Util.Allocate(text_byteCount + 1);
}
else
{
byte* native_text_stackBytes = stackalloc byte[text_byteCount + 1];
native_text = native_text_stackBytes;
}
int native_text_offset = Util.GetUtf8(text, native_text, text_byteCount);
native_text[native_text_offset] = 0;
}
else { native_text = null; }
byte* native_text_end = null;
ImGuiNative.ImGuiInputTextCallbackData_InsertChars(NativePtr, pos, native_text, native_text_end);
if (text_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_text);
}
}
}
}

@ -39,19 +39,28 @@ namespace ImGuiNET
public bool IsDataType(string type)
{
byte* native_type;
int type_byteCount = 0;
if (type != null)
{
int type_byteCount = Encoding.UTF8.GetByteCount(type);
byte* native_type_stackBytes = stackalloc byte[type_byteCount + 1];
native_type = native_type_stackBytes;
fixed (char* type_ptr = type)
type_byteCount = Encoding.UTF8.GetByteCount(type);
if (type_byteCount > Util.StackAllocationSizeLimit)
{
int native_type_offset = Encoding.UTF8.GetBytes(type_ptr, type.Length, native_type, type_byteCount);
native_type[native_type_offset] = 0;
native_type = Util.Allocate(type_byteCount + 1);
}
else
{
byte* native_type_stackBytes = stackalloc byte[type_byteCount + 1];
native_type = native_type_stackBytes;
}
int native_type_offset = Util.GetUtf8(type, native_type, type_byteCount);
native_type[native_type_offset] = 0;
}
else { native_type = null; }
byte ret = ImGuiNative.ImGuiPayload_IsDataType(NativePtr, native_type);
if (type_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_type);
}
return ret != 0;
}
public bool IsDelivery()

@ -21,19 +21,28 @@ namespace ImGuiNET
public void appendf(string fmt)
{
byte* native_fmt;
int fmt_byteCount = 0;
if (fmt != null)
{
int fmt_byteCount = Encoding.UTF8.GetByteCount(fmt);
byte* native_fmt_stackBytes = stackalloc byte[fmt_byteCount + 1];
native_fmt = native_fmt_stackBytes;
fixed (char* fmt_ptr = fmt)
fmt_byteCount = Encoding.UTF8.GetByteCount(fmt);
if (fmt_byteCount > Util.StackAllocationSizeLimit)
{
int native_fmt_offset = Encoding.UTF8.GetBytes(fmt_ptr, fmt.Length, native_fmt, fmt_byteCount);
native_fmt[native_fmt_offset] = 0;
native_fmt = Util.Allocate(fmt_byteCount + 1);
}
else
{
byte* native_fmt_stackBytes = stackalloc byte[fmt_byteCount + 1];
native_fmt = native_fmt_stackBytes;
}
int native_fmt_offset = Util.GetUtf8(fmt, native_fmt, fmt_byteCount);
native_fmt[native_fmt_offset] = 0;
}
else { native_fmt = null; }
ImGuiNative.ImGuiTextBuffer_appendf(NativePtr, native_fmt);
if (fmt_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_fmt);
}
}
public string begin()
{

@ -33,53 +33,80 @@ namespace ImGuiNET
public bool Draw()
{
byte* native_label;
int label_byteCount = Encoding.UTF8.GetByteCount("Filter(inc,-exc)");
byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1];
native_label = native_label_stackBytes;
fixed (char* label_ptr = "Filter(inc,-exc)")
int label_byteCount = 0;
label_byteCount = Encoding.UTF8.GetByteCount("Filter(inc,-exc)");
if (label_byteCount > Util.StackAllocationSizeLimit)
{
int native_label_offset = Encoding.UTF8.GetBytes(label_ptr, "Filter(inc,-exc)".Length, native_label, label_byteCount);
native_label[native_label_offset] = 0;
native_label = Util.Allocate(label_byteCount + 1);
}
else
{
byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1];
native_label = native_label_stackBytes;
}
int native_label_offset = Util.GetUtf8("Filter(inc,-exc)", native_label, label_byteCount);
native_label[native_label_offset] = 0;
float width = 0.0f;
byte ret = ImGuiNative.ImGuiTextFilter_Draw(NativePtr, native_label, width);
if (label_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_label);
}
return ret != 0;
}
public bool Draw(string label)
{
byte* native_label;
int label_byteCount = 0;
if (label != null)
{
int label_byteCount = Encoding.UTF8.GetByteCount(label);
byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1];
native_label = native_label_stackBytes;
fixed (char* label_ptr = label)
label_byteCount = Encoding.UTF8.GetByteCount(label);
if (label_byteCount > Util.StackAllocationSizeLimit)
{
int native_label_offset = Encoding.UTF8.GetBytes(label_ptr, label.Length, native_label, label_byteCount);
native_label[native_label_offset] = 0;
native_label = Util.Allocate(label_byteCount + 1);
}
else
{
byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1];
native_label = native_label_stackBytes;
}
int native_label_offset = Util.GetUtf8(label, native_label, label_byteCount);
native_label[native_label_offset] = 0;
}
else { native_label = null; }
float width = 0.0f;
byte ret = ImGuiNative.ImGuiTextFilter_Draw(NativePtr, native_label, width);
if (label_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_label);
}
return ret != 0;
}
public bool Draw(string label, float width)
{
byte* native_label;
int label_byteCount = 0;
if (label != null)
{
int label_byteCount = Encoding.UTF8.GetByteCount(label);
byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1];
native_label = native_label_stackBytes;
fixed (char* label_ptr = label)
label_byteCount = Encoding.UTF8.GetByteCount(label);
if (label_byteCount > Util.StackAllocationSizeLimit)
{
int native_label_offset = Encoding.UTF8.GetBytes(label_ptr, label.Length, native_label, label_byteCount);
native_label[native_label_offset] = 0;
native_label = Util.Allocate(label_byteCount + 1);
}
else
{
byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1];
native_label = native_label_stackBytes;
}
int native_label_offset = Util.GetUtf8(label, native_label, label_byteCount);
native_label[native_label_offset] = 0;
}
else { native_label = null; }
byte ret = ImGuiNative.ImGuiTextFilter_Draw(NativePtr, native_label, width);
if (label_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_label);
}
return ret != 0;
}
public bool IsActive()
@ -90,20 +117,29 @@ namespace ImGuiNET
public bool PassFilter(string text)
{
byte* native_text;
int text_byteCount = 0;
if (text != null)
{
int text_byteCount = Encoding.UTF8.GetByteCount(text);
byte* native_text_stackBytes = stackalloc byte[text_byteCount + 1];
native_text = native_text_stackBytes;
fixed (char* text_ptr = text)
text_byteCount = Encoding.UTF8.GetByteCount(text);
if (text_byteCount > Util.StackAllocationSizeLimit)
{
int native_text_offset = Encoding.UTF8.GetBytes(text_ptr, text.Length, native_text, text_byteCount);
native_text[native_text_offset] = 0;
native_text = Util.Allocate(text_byteCount + 1);
}
else
{
byte* native_text_stackBytes = stackalloc byte[text_byteCount + 1];
native_text = native_text_stackBytes;
}
int native_text_offset = Util.GetUtf8(text, native_text, text_byteCount);
native_text[native_text_offset] = 0;
}
else { native_text = null; }
byte* native_text_end = null;
byte ret = ImGuiNative.ImGuiTextFilter_PassFilter(NativePtr, native_text, native_text_end);
if (text_byteCount > Util.StackAllocationSizeLimit)
{
Util.Free(native_text);
}
return ret != 0;
}
}

@ -1,6 +1,7 @@
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace ImGuiNET
@ -42,18 +43,31 @@ namespace ImGuiNET
ImGuiInputTextCallback callback,
IntPtr user_data)
{
int labelByteCount = Encoding.UTF8.GetByteCount(label);
byte* labelBytes = stackalloc byte[labelByteCount + 1];
fixed (char* labelPtr = label)
int utf8LabelByteCount = Encoding.UTF8.GetByteCount(label);
byte* utf8LabelBytes;
if (utf8LabelByteCount > Util.StackAllocationSizeLimit)
{
utf8LabelBytes = Util.Allocate(utf8LabelByteCount + 1);
}
else
{
Encoding.UTF8.GetBytes(labelPtr, label.Length, labelBytes, labelByteCount);
byte* stackPtr = stackalloc byte[utf8LabelByteCount + 1];
utf8LabelBytes = stackPtr;
}
Util.GetUtf8(label, utf8LabelBytes, utf8LabelByteCount);
bool ret;
fixed (byte* bufPtr = buf)
{
return ImGuiNative.igInputText(labelBytes, bufPtr, buf_size, flags, callback, user_data.ToPointer()) != 0;
ret = ImGuiNative.igInputText(utf8LabelBytes, bufPtr, buf_size, flags, callback, user_data.ToPointer()) != 0;
}
if (utf8LabelByteCount > Util.StackAllocationSizeLimit)
{
Util.Free(utf8LabelBytes);
}
return ret;
}
public static bool InputText(
@ -82,34 +96,61 @@ namespace ImGuiNET
ImGuiInputTextCallback callback,
IntPtr user_data)
{
int labelByteCount = Encoding.UTF8.GetByteCount(label);
byte* labelBytes = stackalloc byte[labelByteCount + 1];
fixed (char* labelPtr = label)
int utf8LabelByteCount = Encoding.UTF8.GetByteCount(label);
byte* utf8LabelBytes;
if (utf8LabelByteCount > Util.StackAllocationSizeLimit)
{
Encoding.UTF8.GetBytes(labelPtr, label.Length, labelBytes, labelByteCount);
utf8LabelBytes = Util.Allocate(utf8LabelByteCount + 1);
}
int originalByteCount = Encoding.UTF8.GetByteCount(input);
int stackBufSize = Math.Max((int)maxLength, originalByteCount);
byte* bufBytes = stackalloc byte[stackBufSize];
fixed (char* u16Ptr = input)
else
{
Encoding.UTF8.GetBytes(u16Ptr, input.Length, bufBytes, stackBufSize);
byte* stackPtr = stackalloc byte[utf8LabelByteCount + 1];
utf8LabelBytes = stackPtr;
}
Util.GetUtf8(label, utf8LabelBytes, utf8LabelByteCount);
byte* originalBufBytes = stackalloc byte[originalByteCount];
Unsafe.CopyBlock(originalBufBytes, bufBytes, (uint)originalByteCount);
int utf8InputByteCount = Encoding.UTF8.GetByteCount(input);
int inputBufSize = Math.Max((int)maxLength + 1, utf8InputByteCount + 1);
byte* utf8InputBytes;
byte* originalUtf8InputBytes;
if (inputBufSize > Util.StackAllocationSizeLimit)
{
utf8InputBytes = Util.Allocate(inputBufSize);
originalUtf8InputBytes = Util.Allocate(inputBufSize);
}
else
{
byte* inputStackBytes = stackalloc byte[inputBufSize];
utf8InputBytes = inputStackBytes;
byte* originalInputStackBytes = stackalloc byte[inputBufSize];
originalUtf8InputBytes = originalInputStackBytes;
}
Util.GetUtf8(input, utf8InputBytes, inputBufSize);
uint clearBytesCount = (uint)(inputBufSize - utf8InputByteCount);
Unsafe.InitBlockUnaligned(utf8InputBytes + utf8InputByteCount + 1, 0, clearBytesCount);
Unsafe.CopyBlock(originalUtf8InputBytes, utf8InputBytes, (uint)inputBufSize);
byte result = ImGuiNative.igInputText(
labelBytes,
bufBytes,
(uint)stackBufSize,
utf8LabelBytes,
utf8InputBytes,
(uint)inputBufSize,
flags,
callback,
user_data.ToPointer());
if (!Util.AreStringsEqual(originalBufBytes, originalByteCount, bufBytes))
if (!Util.AreStringsEqual(originalUtf8InputBytes, inputBufSize, utf8InputBytes))
{
input = Util.StringFromPtr(utf8InputBytes);
}
if (utf8LabelByteCount > Util.StackAllocationSizeLimit)
{
input = Util.StringFromPtr(bufBytes);
Util.Free(utf8LabelBytes);
}
if (inputBufSize > Util.StackAllocationSizeLimit)
{
Util.Free(utf8InputBytes);
Util.Free(originalUtf8InputBytes);
}
return result != 0;
@ -145,35 +186,62 @@ namespace ImGuiNET
ImGuiInputTextCallback callback,
IntPtr user_data)
{
int labelByteCount = Encoding.UTF8.GetByteCount(label);
byte* labelBytes = stackalloc byte[labelByteCount + 1];
fixed (char* labelPtr = label)
int utf8LabelByteCount = Encoding.UTF8.GetByteCount(label);
byte* utf8LabelBytes;
if (utf8LabelByteCount > Util.StackAllocationSizeLimit)
{
Encoding.UTF8.GetBytes(labelPtr, label.Length, labelBytes, labelByteCount);
utf8LabelBytes = Util.Allocate(utf8LabelByteCount + 1);
}
int originalByteCount = Encoding.UTF8.GetByteCount(input);
int stackBufSize = Math.Max((int)maxLength, originalByteCount);
byte* bufBytes = stackalloc byte[stackBufSize];
fixed (char* u16Ptr = input)
else
{
Encoding.UTF8.GetBytes(u16Ptr, input.Length, bufBytes, stackBufSize);
byte* stackPtr = stackalloc byte[utf8LabelByteCount + 1];
utf8LabelBytes = stackPtr;
}
Util.GetUtf8(label, utf8LabelBytes, utf8LabelByteCount);
byte* originalBufBytes = stackalloc byte[originalByteCount];
Unsafe.CopyBlock(originalBufBytes, bufBytes, (uint)originalByteCount);
int utf8InputByteCount = Encoding.UTF8.GetByteCount(input);
int inputBufSize = Math.Max((int)maxLength + 1, utf8InputByteCount + 1);
byte* utf8InputBytes;
byte* originalUtf8InputBytes;
if (inputBufSize > Util.StackAllocationSizeLimit)
{
utf8InputBytes = Util.Allocate(inputBufSize);
originalUtf8InputBytes = Util.Allocate(inputBufSize);
}
else
{
byte* inputStackBytes = stackalloc byte[inputBufSize];
utf8InputBytes = inputStackBytes;
byte* originalInputStackBytes = stackalloc byte[inputBufSize];
originalUtf8InputBytes = originalInputStackBytes;
}
Util.GetUtf8(input, utf8InputBytes, inputBufSize);
uint clearBytesCount = (uint)(inputBufSize - utf8InputByteCount);
Unsafe.InitBlockUnaligned(utf8InputBytes + utf8InputByteCount + 1, 0, clearBytesCount);
Unsafe.CopyBlock(originalUtf8InputBytes, utf8InputBytes, (uint)inputBufSize);
byte result = ImGuiNative.igInputTextMultiline(
labelBytes,
bufBytes,
(uint)stackBufSize,
utf8LabelBytes,
utf8InputBytes,
(uint)inputBufSize,
size,
flags,
callback,
user_data.ToPointer());
if (!Util.AreStringsEqual(originalBufBytes, originalByteCount, bufBytes))
if (!Util.AreStringsEqual(originalUtf8InputBytes, inputBufSize, utf8InputBytes))
{
input = Util.StringFromPtr(utf8InputBytes);
}
if (utf8LabelByteCount > Util.StackAllocationSizeLimit)
{
Util.Free(utf8LabelBytes);
}
if (inputBufSize > Util.StackAllocationSizeLimit)
{
input = Util.StringFromPtr(bufBytes);
Util.Free(utf8InputBytes);
Util.Free(originalUtf8InputBytes);
}
return result != 0;
@ -214,28 +282,52 @@ namespace ImGuiNET
ImGuiInputTextCallback callback,
IntPtr user_data)
{
int utf8LabelByteCount = Encoding.UTF8.GetByteCount(label);
byte* utf8LabelBytes;
if (utf8LabelByteCount > Util.StackAllocationSizeLimit)
{
utf8LabelBytes = Util.Allocate(utf8LabelByteCount + 1);
}
else
{
byte* stackPtr = stackalloc byte[utf8LabelByteCount + 1];
utf8LabelBytes = stackPtr;
}
Util.GetUtf8(label, utf8LabelBytes, utf8LabelByteCount);
bool ret = ImGuiNative.igInputText(utf8LabelBytes, (byte*)buf.ToPointer(), buf_size, flags, callback, user_data.ToPointer()) != 0;
int labelByteCount = Encoding.UTF8.GetByteCount(label);
byte* labelBytes = stackalloc byte[labelByteCount + 1];
fixed (char* labelPtr = label)
if (utf8LabelByteCount > Util.StackAllocationSizeLimit)
{
Encoding.UTF8.GetBytes(labelPtr, label.Length, labelBytes, labelByteCount);
Util.Free(utf8LabelBytes);
}
return ImGuiNative.igInputText(labelBytes, (byte*)buf.ToPointer(), buf_size, flags, callback, user_data.ToPointer()) != 0;
return ret;
}
public static bool Begin(string name, ImGuiWindowFlags flags)
{
int name_byteCount = Encoding.UTF8.GetByteCount(name);
byte* native_name = stackalloc byte[name_byteCount + 1];
fixed (char* name_ptr = name)
int utf8NameByteCount = Encoding.UTF8.GetByteCount(name);
byte* utf8NameBytes;
if (utf8NameByteCount > Util.StackAllocationSizeLimit)
{
utf8NameBytes = Util.Allocate(utf8NameByteCount + 1);
}
else
{
int native_name_offset = Encoding.UTF8.GetBytes(name_ptr, name.Length, native_name, name_byteCount);
native_name[native_name_offset] = 0;
byte* stackPtr = stackalloc byte[utf8NameByteCount + 1];
utf8NameBytes = stackPtr;
}
Util.GetUtf8(name, utf8NameBytes, utf8NameByteCount);
byte* p_open = null;
byte ret = ImGuiNative.igBegin(native_name, p_open, flags);
byte ret = ImGuiNative.igBegin(utf8NameBytes, p_open, flags);
if (utf8NameByteCount > Util.StackAllocationSizeLimit)
{
Util.Free(utf8NameBytes);
}
return ret != 0;
}

@ -1,10 +1,14 @@
using System.Text;
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace ImGuiNET
{
internal static class Util
internal static unsafe class Util
{
public static unsafe string StringFromPtr(byte* ptr)
internal const int StackAllocationSizeLimit = 2048;
public static string StringFromPtr(byte* ptr)
{
int characters = 0;
while (ptr[characters] != 0)
@ -15,7 +19,7 @@ namespace ImGuiNET
return Encoding.UTF8.GetString(ptr, characters);
}
internal static unsafe bool AreStringsEqual(byte* a, int aLength, byte* b)
internal static bool AreStringsEqual(byte* a, int aLength, byte* b)
{
for (int i = 0; i < aLength; i++)
{
@ -26,5 +30,15 @@ namespace ImGuiNET
return true;
}
internal static byte* Allocate(int byteCount) => (byte*)Marshal.AllocHGlobal(byteCount);
internal static void Free(byte* ptr) => Marshal.FreeHGlobal((IntPtr)ptr);
internal static int GetUtf8(string s, byte* utf8Bytes, int utf8ByteCount)
{
fixed (char* utf16Ptr = s)
{
return Encoding.UTF8.GetBytes(utf16Ptr, s.Length, utf8Bytes, utf8ByteCount);
}
}
}
}

Loading…
Cancel
Save