mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
68 lines
No EOL
1.9 KiB
C#
68 lines
No EOL
1.9 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using Penumbra.GameData.Util;
|
|
|
|
namespace Penumbra.GameData.ByteString;
|
|
|
|
public static unsafe partial class ByteStringFunctions
|
|
{
|
|
// Used for static null-terminators.
|
|
public class NullTerminator
|
|
{
|
|
public readonly byte* NullBytePtr;
|
|
|
|
public NullTerminator()
|
|
{
|
|
NullBytePtr = ( byte* )Marshal.AllocHGlobal( 1 );
|
|
*NullBytePtr = 0;
|
|
}
|
|
|
|
~NullTerminator()
|
|
=> Marshal.FreeHGlobal( ( IntPtr )NullBytePtr );
|
|
}
|
|
|
|
// Convert a C# unicode-string to an unmanaged UTF8-byte array and return the pointer.
|
|
// If the length would exceed the given maxLength, return a nullpointer instead.
|
|
public static byte* Utf8FromString( string s, out int length, int maxLength = int.MaxValue )
|
|
{
|
|
length = Encoding.UTF8.GetByteCount( s );
|
|
if( length >= maxLength )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var path = ( byte* )Marshal.AllocHGlobal( length + 1 );
|
|
fixed( char* ptr = s )
|
|
{
|
|
Encoding.UTF8.GetBytes( ptr, length, path, length + 1 );
|
|
}
|
|
|
|
path[ length ] = 0;
|
|
return path;
|
|
}
|
|
|
|
// Create a copy of a given string and return the pointer.
|
|
public static byte* CopyString( byte* path, int length )
|
|
{
|
|
var ret = ( byte* )Marshal.AllocHGlobal( length + 1 );
|
|
Functions.MemCpyUnchecked( ret, path, length );
|
|
ret[ length ] = 0;
|
|
return ret;
|
|
}
|
|
|
|
// Check the length of a null-terminated byte array no longer than the given maxLength.
|
|
public static int CheckLength( byte* path, int maxLength = int.MaxValue )
|
|
{
|
|
var end = path + maxLength;
|
|
for( var it = path; it < end; ++it )
|
|
{
|
|
if( *it == 0 )
|
|
{
|
|
return ( int )( it - path );
|
|
}
|
|
}
|
|
|
|
throw new ArgumentOutOfRangeException( "Null-terminated path too long" );
|
|
}
|
|
} |