mirror of
https://github.com/raylib-cs/raylib-cs
synced 2025-09-09 03:01:41 -04:00
Update string handling
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
using Raylib_cs;
|
||||||
|
|
||||||
namespace Raylib_cs.Tests
|
namespace Raylib_cs.Tests
|
||||||
{
|
{
|
||||||
@@ -39,5 +40,26 @@ namespace Raylib_cs.Tests
|
|||||||
Assert.True(BlittableHelper.IsBlittable<VrStereoConfig>());
|
Assert.True(BlittableHelper.IsBlittable<VrStereoConfig>());
|
||||||
Assert.True(BlittableHelper.IsBlittable<RenderBatch>());
|
Assert.True(BlittableHelper.IsBlittable<RenderBatch>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Debug()
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
Raylib.InitWindow(screenWidth, screenHeight, "Aaåäö");
|
||||||
|
|
||||||
|
while (!Raylib.WindowShouldClose())
|
||||||
|
{
|
||||||
|
Raylib.BeginDrawing();
|
||||||
|
Raylib.ClearBackground(Color.RAYWHITE);
|
||||||
|
Raylib.EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
Raylib.CloseWindow();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
namespace Raylib_cs
|
namespace Raylib_cs
|
||||||
{
|
{
|
||||||
@@ -75,7 +76,15 @@ namespace Raylib_cs
|
|||||||
|
|
||||||
/// <summary>Initialize window and OpenGL context</summary>
|
/// <summary>Initialize window and OpenGL context</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void InitWindow(int width, int height, [MarshalAs(UnmanagedType.LPUTF8Str)] string title);
|
public static extern void InitWindow(int width, int height, byte* title);
|
||||||
|
|
||||||
|
public static void InitWindow(int width, int height, Utf8String title)
|
||||||
|
{
|
||||||
|
fixed (byte* p = title)
|
||||||
|
{
|
||||||
|
InitWindow(width, height, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Check if KEY_ESCAPE pressed or Close icon pressed</summary>
|
/// <summary>Check if KEY_ESCAPE pressed or Close icon pressed</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
@@ -147,7 +156,15 @@ namespace Raylib_cs
|
|||||||
|
|
||||||
/// <summary>Set title for window (only PLATFORM_DESKTOP)</summary>
|
/// <summary>Set title for window (only PLATFORM_DESKTOP)</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void SetWindowTitle([MarshalAs(UnmanagedType.LPUTF8Str)] string title);
|
public static extern void SetWindowTitle(byte* title);
|
||||||
|
|
||||||
|
public static void SetWindowTitle(Utf8String title)
|
||||||
|
{
|
||||||
|
fixed (byte* p = title)
|
||||||
|
{
|
||||||
|
SetWindowTitle(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Set window position on screen (only PLATFORM_DESKTOP)</summary>
|
/// <summary>Set window position on screen (only PLATFORM_DESKTOP)</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
@@ -239,7 +256,15 @@ namespace Raylib_cs
|
|||||||
|
|
||||||
/// <summary>Set clipboard text content</summary>
|
/// <summary>Set clipboard text content</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void SetClipboardText([MarshalAs(UnmanagedType.LPUTF8Str)] string text);
|
public static extern void SetClipboardText(byte* text);
|
||||||
|
|
||||||
|
public static void SetClipboardText(Utf8String text)
|
||||||
|
{
|
||||||
|
fixed (byte* p = text)
|
||||||
|
{
|
||||||
|
SetClipboardText(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Custom frame control functions
|
// Custom frame control functions
|
||||||
// NOTE: Those functions are intended for advance users that want full control over the frame processing
|
// NOTE: Those functions are intended for advance users that want full control over the frame processing
|
||||||
@@ -1101,11 +1126,26 @@ namespace Raylib_cs
|
|||||||
|
|
||||||
/// <summary>Create an image from text (default font)</summary>
|
/// <summary>Create an image from text (default font)</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern Image ImageText([MarshalAs(UnmanagedType.LPUTF8Str)] string text, int fontSize, Color color);
|
public static extern Image ImageText(byte* text, int fontSize, Color color);
|
||||||
|
|
||||||
|
public static Image ImageText(Utf8String text, int fontSize, Color color)
|
||||||
|
{
|
||||||
|
fixed (byte* p = text)
|
||||||
|
{
|
||||||
|
return ImageText(p, fontSize, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Create an image from text (custom sprite font)</summary>
|
/// <summary>Create an image from text (custom sprite font)</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern Image ImageTextEx(Font font, [MarshalAs(UnmanagedType.LPUTF8Str)] string text, float fontSize, float spacing, Color tint);
|
public static extern Image ImageTextEx(Font font, byte* text, float fontSize, float spacing, Color tint);
|
||||||
|
public static Image ImageTextEx(Font font, Utf8String text, float fontSize, float spacing, Color tint)
|
||||||
|
{
|
||||||
|
fixed (byte* p = text)
|
||||||
|
{
|
||||||
|
return ImageTextEx(font, p, fontSize, spacing, tint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Convert image to POT (power-of-two)</summary>
|
/// <summary>Convert image to POT (power-of-two)</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
@@ -1273,12 +1313,27 @@ namespace Raylib_cs
|
|||||||
|
|
||||||
/// <summary>Draw text (using default font) within an image (destination)</summary>
|
/// <summary>Draw text (using default font) within an image (destination)</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void ImageDrawText(ref Image dst, [MarshalAs(UnmanagedType.LPUTF8Str)] string text, int x, int y, int fontSize, Color color);
|
public static extern void ImageDrawText(ref Image dst, byte* text, int x, int y, int fontSize, Color color);
|
||||||
|
|
||||||
|
public static void ImageDrawText(ref Image dst, Utf8String text, int x, int y, int fontSize, Color color)
|
||||||
|
{
|
||||||
|
fixed (byte* p = text)
|
||||||
|
{
|
||||||
|
ImageDrawText(ref dst, p, x,y,fontSize,color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Draw text (custom sprite font) within an image (destination)</summary>
|
/// <summary>Draw text (custom sprite font) within an image (destination)</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void ImageDrawTextEx(ref Image dst, Font font, [MarshalAs(UnmanagedType.LPUTF8Str)] string text, Vector2 position, float fontSize, float spacing, Color tint);
|
public static extern void ImageDrawTextEx(ref Image dst, Font font, byte* text, Vector2 position, float fontSize, float spacing, Color tint);
|
||||||
|
|
||||||
|
public static void ImageDrawTextEx(ref Image dst, Font font, Utf8String text, Vector2 position, float fontSize, float spacing, Color tint)
|
||||||
|
{
|
||||||
|
fixed (byte* p = text)
|
||||||
|
{
|
||||||
|
ImageDrawTextEx(ref dst, font, p, position, fontSize, spacing, tint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Texture loading functions
|
// Texture loading functions
|
||||||
// NOTE: These functions require GPU access
|
// NOTE: These functions require GPU access
|
||||||
@@ -1469,15 +1524,42 @@ namespace Raylib_cs
|
|||||||
|
|
||||||
/// <summary>Draw text (using default font)</summary>
|
/// <summary>Draw text (using default font)</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void DrawText([MarshalAs(UnmanagedType.LPUTF8Str)] string text, int posX, int posY, int fontSize, Color color);
|
public static extern void DrawText(byte* text, int posX, int posY, int fontSize, Color color);
|
||||||
|
|
||||||
|
public static void DrawText(Utf8String text, int posX, int posY, int fontSize, Color color)
|
||||||
|
{
|
||||||
|
fixed (byte* p = text)
|
||||||
|
{
|
||||||
|
DrawText(p, posX, posY, fontSize, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Draw text using font and additional parameters</summary>
|
/// <summary>Draw text using font and additional parameters</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void DrawTextEx(Font font, [MarshalAs(UnmanagedType.LPUTF8Str)] string text, Vector2 position, float fontSize, float spacing, Color tint);
|
public static extern void DrawTextEx(Font font, byte* text, Vector2 position, float fontSize, float spacing, Color tint);
|
||||||
|
|
||||||
|
public static void DrawTextEx(Font font, Utf8String text, Vector2 position, float fontSize,
|
||||||
|
float spacing, Color tint)
|
||||||
|
{
|
||||||
|
fixed (byte* p = text)
|
||||||
|
{
|
||||||
|
DrawTextEx(font, p, position, fontSize, spacing, tint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Draw text using Font and pro parameters (rotation)</summary>
|
/// <summary>Draw text using Font and pro parameters (rotation)</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void DrawTextPro(Font font, [MarshalAs(UnmanagedType.LPUTF8Str)] string text, Vector2 position, float fontSize, float spacing, Color tint);
|
public static extern void DrawTextPro(Font font, byte* text, Vector2 position, float fontSize, float spacing, Color tint);
|
||||||
|
|
||||||
|
public static void DrawTextPro(Font font, Utf8String text, Vector2 position, float fontSize,
|
||||||
|
float spacing, Color tint)
|
||||||
|
{
|
||||||
|
fixed (byte* p = text)
|
||||||
|
{
|
||||||
|
DrawTextEx(font, p, position, fontSize, spacing, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Draw one character (codepoint)</summary>
|
/// <summary>Draw one character (codepoint)</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
@@ -1488,11 +1570,27 @@ namespace Raylib_cs
|
|||||||
|
|
||||||
/// <summary>Measure string width for default font</summary>
|
/// <summary>Measure string width for default font</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern int MeasureText([MarshalAs(UnmanagedType.LPUTF8Str)] string text, int fontSize);
|
public static extern int MeasureText(byte* text, int fontSize);
|
||||||
|
|
||||||
|
public static int MeasureText(Utf8String text, int fontSize)
|
||||||
|
{
|
||||||
|
fixed (byte* p = text)
|
||||||
|
{
|
||||||
|
return MeasureText(p, fontSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Measure string size for Font</summary>
|
/// <summary>Measure string size for Font</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern Vector2 MeasureTextEx(Font font, [MarshalAs(UnmanagedType.LPUTF8Str)] string text, float fontSize, float spacing);
|
public static extern Vector2 MeasureTextEx(Font font, byte* text, float fontSize, float spacing);
|
||||||
|
|
||||||
|
public static Vector2 MeasureTextEx(Font font, Utf8String text, float fontSize, float spacing)
|
||||||
|
{
|
||||||
|
fixed (byte* p = text)
|
||||||
|
{
|
||||||
|
return MeasureTextEx(font, p, fontSize, spacing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found</summary>
|
/// <summary>Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found</summary>
|
||||||
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
220
Raylib-cs/Utf8String.cs
Normal file
220
Raylib-cs/Utf8String.cs
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Raylib_cs;
|
||||||
|
|
||||||
|
#region LICENSE
|
||||||
|
|
||||||
|
// ** -- TAKEN FROM SQLitePCL.raw -- ** \\
|
||||||
|
/* https://github.com/ericsink/SQLitePCL.raw */
|
||||||
|
/*
|
||||||
|
Copyright 2014-2021 SourceGear, LLC
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// CHANGES:
|
||||||
|
// - Update Method Names
|
||||||
|
// - Implicit Conversion From string
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A raw string representation suitable for passing into many core SQLite apis. These will normally be pointers to
|
||||||
|
/// utf8 encoded bytes, with a trailing <c>\0</c> terminator. <see langword="null"/> strings can be represented as
|
||||||
|
/// well as empty strings.
|
||||||
|
/// </summary>
|
||||||
|
public readonly ref struct Utf8String
|
||||||
|
{
|
||||||
|
// this span will contain a zero terminator byte
|
||||||
|
// if sp.Length is 0, it represents a null string
|
||||||
|
// if sp.Length is 1, the only byte must be zero, and it is an empty string
|
||||||
|
readonly ReadOnlySpan<byte> sp;
|
||||||
|
|
||||||
|
public ref readonly byte GetPinnableReference()
|
||||||
|
{
|
||||||
|
return ref sp.GetPinnableReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Utf8String(ReadOnlySpan<byte> a)
|
||||||
|
{
|
||||||
|
// no check here. anything that calls this
|
||||||
|
// constructor must make assurances about the
|
||||||
|
// zero terminator.
|
||||||
|
sp = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of <see cref="Utf8String"/> which directly points at the memory pointed to by <paramref
|
||||||
|
/// name="span"/>. The span must contain a valid <see cref="Encoding.UTF8"/> encoded block of memory that
|
||||||
|
/// terminates with a <c>\0</c> byte. The span passed in must include the <c>\0</c> terminator.
|
||||||
|
/// <para/>
|
||||||
|
/// Both <see langword="null"/> and empty strings can be created here. To create a <see langword="null"/> string,
|
||||||
|
/// pass in an empty <see cref="ReadOnlySpan{T}"/>. To create an empty string, pass in a span with length 1, that
|
||||||
|
/// only contains a <c>\0</c>
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// Thrown if <c>span.Length > 0</c> and <c>span[^1]</c> is not <c>\0</c>.
|
||||||
|
/// </exception>
|
||||||
|
public static Utf8String FromSpan(ReadOnlySpan<byte> span)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
(span.Length > 0)
|
||||||
|
&& (span[^1] != 0)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("zero terminator required");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Utf8String(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Utf8String FromString(string s)
|
||||||
|
{
|
||||||
|
if (s == null)
|
||||||
|
{
|
||||||
|
return new Utf8String(ReadOnlySpan<byte>.Empty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new Utf8String(s.ToUtf8String());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsafe long GetLength(byte* p)
|
||||||
|
{
|
||||||
|
var q = p;
|
||||||
|
while (*q != 0)
|
||||||
|
{
|
||||||
|
q++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return q - p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsafe ReadOnlySpan<byte> FindZeroTerminator(byte* p)
|
||||||
|
{
|
||||||
|
var len = (int)GetLength(p);
|
||||||
|
return new ReadOnlySpan<byte>(p, len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of <see cref="Utf8String"/> which directly points at the memory pointed to by <paramref
|
||||||
|
/// name="p"/>. The pointer must either be <see langword="null"/> or point to a valid <see
|
||||||
|
/// cref="Encoding.UTF8"/> encoded block of memory that terminates with a <c>\0</c> byte.
|
||||||
|
/// </summary>
|
||||||
|
public static unsafe Utf8String FromPtr(byte* p)
|
||||||
|
{
|
||||||
|
if (p == null)
|
||||||
|
{
|
||||||
|
return new Utf8String(ReadOnlySpan<byte>.Empty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new Utf8String(FindZeroTerminator(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO maybe remove this and just use FromSpan?
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of <see cref="Utf8String"/> which directly points at the memory pointed to by <paramref
|
||||||
|
/// name="p"/> with length <paramref name="len"/>. The pointer must be to a valid <see cref="Encoding.UTF8"/>
|
||||||
|
/// encoded block of memory that terminates with a <c>\0</c> byte. The <paramref name="len"/> value refers to
|
||||||
|
/// the number of bytes in the utf8 encoded value <em>not</em> including the <c>\0</c> byte terminator.
|
||||||
|
/// <para/>
|
||||||
|
/// <paramref name="p"/> can be <see langword="null"/>, in which case <paramref name="len"/> is ignored
|
||||||
|
/// and a new <see cref="Utf8String"/> instance is created that represents <see langword="null"/>. Note that this
|
||||||
|
/// different from a pointer to a single <c>\0</c> byte and a length of one. That would represent an empty <see
|
||||||
|
/// cref="Utf8String"/> string.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// Thrown if <paramref name="p"/> is not <see langword="null"/> and <c>p[len]</c> is not <c>\0</c>.
|
||||||
|
/// </exception>
|
||||||
|
public static unsafe Utf8String FromPtrLen(byte* p, int len)
|
||||||
|
{
|
||||||
|
if (p == null)
|
||||||
|
{
|
||||||
|
return new Utf8String(ReadOnlySpan<byte>.Empty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// the given len does NOT include the zero terminator
|
||||||
|
var sp = new ReadOnlySpan<byte>(p, len + 1);
|
||||||
|
return FromSpan(sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe Utf8String FromIntPtr(IntPtr p)
|
||||||
|
{
|
||||||
|
if (p == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return new Utf8String(ReadOnlySpan<byte>.Empty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new Utf8String(FindZeroTerminator((byte*)(p.ToPointer())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (sp.Length == 0)
|
||||||
|
{
|
||||||
|
return "NUL";
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (byte* q = sp)
|
||||||
|
{
|
||||||
|
return Encoding.UTF8.GetString(q, sp.Length - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="Encoding.UTF8"/> encoded bytes for the provided <paramref name="value"/>. The array
|
||||||
|
/// will include a trailing <c>\0</c> character. The length of the array will <see cref="Encoding.UTF8"/>'s
|
||||||
|
/// <see cref="Encoding.GetByteCount(string)"/><c>+1</c> (for the trailing <c>\0</c> byte). These bytes are
|
||||||
|
/// suitable to use with <see cref="FromSpan"/> using the extension <see
|
||||||
|
/// cref="MemoryExtensions.AsSpan{T}(T[])"/> or <see cref="FromPtr(byte*)"/> or <see cref="FromPtrLen(byte*,
|
||||||
|
/// int)"/>. Note that for <see cref="FromPtrLen(byte*, int)"/> the length provided should not include the
|
||||||
|
/// trailing <c>\0</c> terminator.
|
||||||
|
/// </summary>
|
||||||
|
public static byte[] GetZeroTerminatedUTF8Bytes(string value)
|
||||||
|
{
|
||||||
|
return value.ToUtf8String();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Utf8String(string s)
|
||||||
|
{
|
||||||
|
return FromString(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Utf8StringUtils
|
||||||
|
{
|
||||||
|
public static byte[] ToUtf8String(this string sourceText)
|
||||||
|
{
|
||||||
|
if (sourceText == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var length = Encoding.UTF8.GetByteCount(sourceText);
|
||||||
|
|
||||||
|
var byteArray = new byte[length + 1];
|
||||||
|
var wrote = Encoding.UTF8.GetBytes(sourceText, 0, sourceText.Length, byteArray, 0);
|
||||||
|
byteArray[wrote] = 0;
|
||||||
|
|
||||||
|
return byteArray;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user