mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Change most things to new byte strings, introduce new ResourceLoader and Logger fully.
This commit is contained in:
parent
5d77cd5514
commit
f5fccb0235
55 changed files with 2681 additions and 2730 deletions
138
Penumbra.GameData/ByteString/Utf8RelPath.cs
Normal file
138
Penumbra.GameData/ByteString/Utf8RelPath.cs
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Dalamud.Utility;
|
||||
using Microsoft.VisualBasic.CompilerServices;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Penumbra.GameData.ByteString;
|
||||
|
||||
[JsonConverter( typeof( Utf8RelPathConverter ) )]
|
||||
public readonly struct Utf8RelPath : IEquatable< Utf8RelPath >, IComparable< Utf8RelPath >, IDisposable
|
||||
{
|
||||
public const int MaxRelPathLength = 250;
|
||||
|
||||
public readonly Utf8String Path;
|
||||
public static readonly Utf8RelPath Empty = new(Utf8String.Empty);
|
||||
|
||||
internal Utf8RelPath( Utf8String path )
|
||||
=> Path = path;
|
||||
|
||||
|
||||
public static explicit operator Utf8RelPath( string s )
|
||||
=> FromString( s, out var p ) ? p : Empty;
|
||||
|
||||
public static bool FromString( string? s, out Utf8RelPath path )
|
||||
{
|
||||
path = Empty;
|
||||
if( s.IsNullOrEmpty() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var substring = s!.Replace( '/', '\\' );
|
||||
substring.TrimStart( '\\' );
|
||||
if( substring.Length > MaxRelPathLength )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( substring.Length == 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if( !Utf8String.FromString( substring, out var ascii ) || !ascii.IsAscii )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
path = new Utf8RelPath( ascii );
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool FromFile( FileInfo file, DirectoryInfo baseDir, out Utf8RelPath path )
|
||||
{
|
||||
path = Empty;
|
||||
if( !file.FullName.StartsWith( baseDir.FullName ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var substring = file.FullName[ baseDir.FullName.Length.. ];
|
||||
return FromString( substring, out path );
|
||||
}
|
||||
|
||||
public static bool FromFile( FullPath file, DirectoryInfo baseDir, out Utf8RelPath path )
|
||||
{
|
||||
path = Empty;
|
||||
if( !file.FullName.StartsWith( baseDir.FullName ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var substring = file.FullName[ baseDir.FullName.Length.. ];
|
||||
return FromString( substring, out path );
|
||||
}
|
||||
|
||||
public Utf8RelPath( Utf8GamePath gamePath )
|
||||
=> Path = gamePath.Path.Replace( ( byte )'/', ( byte )'\\' );
|
||||
|
||||
public unsafe Utf8GamePath ToGamePath( int skipFolders = 0 )
|
||||
{
|
||||
var idx = 0;
|
||||
while( skipFolders > 0 )
|
||||
{
|
||||
idx = Path.IndexOf( ( byte )'\\', idx ) + 1;
|
||||
--skipFolders;
|
||||
if( idx <= 0 )
|
||||
{
|
||||
return Utf8GamePath.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
var length = Path.Length - idx;
|
||||
var ptr = ByteStringFunctions.CopyString( Path.Path + idx, length );
|
||||
ByteStringFunctions.Replace( ptr, length, ( byte )'\\', ( byte )'/' );
|
||||
ByteStringFunctions.AsciiToLowerInPlace( ptr, length );
|
||||
var utf = new Utf8String().Setup( ptr, length, null, true, true, true, true );
|
||||
return new Utf8GamePath( utf );
|
||||
}
|
||||
|
||||
public int CompareTo( Utf8RelPath rhs )
|
||||
=> Path.CompareTo( rhs.Path );
|
||||
|
||||
public bool Equals( Utf8RelPath other )
|
||||
=> Path.Equals( other.Path );
|
||||
|
||||
public override string ToString()
|
||||
=> Path.ToString();
|
||||
|
||||
public void Dispose()
|
||||
=> Path.Dispose();
|
||||
|
||||
public class Utf8RelPathConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert( Type objectType )
|
||||
=> objectType == typeof( Utf8RelPath );
|
||||
|
||||
public override object ReadJson( JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer )
|
||||
{
|
||||
var token = JToken.Load( reader ).ToString();
|
||||
return FromString( token, out var p )
|
||||
? p
|
||||
: throw new JsonException( $"Could not convert \"{token}\" to {nameof( Utf8RelPath )}." );
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
=> true;
|
||||
|
||||
public override void WriteJson( JsonWriter writer, object? value, JsonSerializer serializer )
|
||||
{
|
||||
if( value is Utf8RelPath p )
|
||||
{
|
||||
serializer.Serialize( writer, p.ToString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue