XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
UTF-8
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text.Json;
using XFEEliteDangerous.Client;

namespace XFEEliteDangerous.Core;

internal sealed unsafe partial class HotNativeReadModule
{
    internal NativeDataReply? InvokeSave(AccountState account,bool selected,byte[] body)
    {
        lock(gate)
        {
            Refresh(false);var module=current;
            if(module is null||module.SaveInvoke==0)return null;
            var request=NativeSaveModuleAdapter.Request(account,selected,body);
            var bytes=JsonSerializer.SerializeToUtf8Bytes(request,NativeReadModuleJson.Default.NativeSaveModuleRequest);
            byte* output=null;var length=0;
            try
            {
                if(bytes.Length>8*1024*1024)throw new NativeDataException(413,"Native save module input exceeds its bound.");
                int result;fixed(byte* input=bytes)result=((delegate* unmanaged<byte*,int,byte**,int*,int>)module.SaveInvoke)(input,bytes.Length,&output,&length);
                if(result==1&&output==null&&length==0)return null;
                if(output==null||length is <=0 or >8*1024*1024)throw new InvalidDataException("Native save module returned an invalid buffer.");
                var reply=JsonSerializer.Deserialize(new ReadOnlySpan<byte>(output,length),NativeReadModuleJson.Default.NativeSaveModuleReply)
                    ??throw new InvalidDataException("Missing native save module reply.");
                if(result!=0||reply.Protocol!=1||reply.ErrorType is not null)
                    OfflineDiagnostics.Current?.Write(result==0?"warning":"error","business.hotload","save.module.diagnostic",
                        "Replaceable native save handler supplied an exact C# diagnostic.",new Dictionary<string,string?>
                        {["generation"]=module.Generation,["httpStatus"]=reply.Status.ToString(),["exceptionType"]=reply.ErrorType,
                            ["error"]=reply.Error,["stackTrace"]=reply.StackTrace});
                if(result!=0)throw new NativeDataException(500,"The active local save handler failed; inspect business.hotload diagnostics.");
                var response=NativeSaveModuleAdapter.Commit(account,reply);
                OfflineDiagnostics.Current?.Write(response.Status>=400?"warning":"debug","business.hotload","save.module.reply",
                    "Native save candidate returned to the fixed host's StateStore transaction.",new Dictionary<string,string?>
                    {["generation"]=module.Generation,["httpStatus"]=response.Status.ToString(),["revision"]=account.Commander.Revision.ToString()});
                return response;
            }
            catch(Exception error)when(error is InvalidDataException or JsonException or ArgumentException)
            {
                OfflineDiagnostics.Current?.Write("error","business.hotload","save.module.contract.failed",
                    "Native save candidate rejected before the durable transaction.",new Dictionary<string,string?>{["generation"]=module.Generation},error);
                throw new NativeDataException(500,"The local save module contract failed; inspect business.hotload diagnostics.");
            }
            finally
            {CryptographicOperations.ZeroMemory(bytes);if(output!=null)((delegate* unmanaged<byte*,void>)module.Free)(output);}
        }
    }
}