using System;
using System.Collections.Generic;
namespace AamCsharp;
public sealed unsafe class AamDocument : IDisposable
{
private SafeAamHandle? _handle;
public AamDocument()
{
_handle = new SafeAamHandle();
}
public static AamDocument Parse(string content)
{
var document = new AamDocument();
try
{
document.CheckResult(AamNative.aam_parse(document.Handle, content));
return document;
}
catch
{
document.Dispose();
throw;
}
}
public static AamDocument Load(string path)
{
var document = new AamDocument();
try
{
document.CheckResult(AamNative.aam_load(document.Handle, path));
return document;
}
catch
{
document.Dispose();
throw;
}
}
public bool IsClosed => _handle is null || _handle.IsClosed || _handle.IsInvalid;
public string Format(string content)
{
var ptr = AamNative.aam_format(Handle, content);
if (ptr == null)
{
var errPtr = AamNative.aam_last_error(Handle);
var message = AamNative.BorrowUtf8String(errPtr) ?? "Native formatting failed";
throw new AamException(message);
}
return AamNative.TakeOwnedUtf8String(ptr)!;
}
public string? Get(string key)
{
return AamNative.TakeOwnedUtf8String(AamNative.aam_get(Handle, key));
}
public Dictionary<string, string> Find(string query)
{
var raw = AamNative.TakeOwnedUtf8String(AamNative.aam_find(Handle, query));
return ParseLineMap(raw);
}
public string[] ReverseSearch(string value)
{
var raw = AamNative.TakeOwnedUtf8String(AamNative.aam_reverse_search(Handle, value));
if (string.IsNullOrWhiteSpace(raw))
{
return Array.Empty<string>();
}
return raw.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
}
public Dictionary<string, string> DeepSearch(string pattern)
{
var raw = AamNative.TakeOwnedUtf8String(AamNative.aam_deep_search(Handle, pattern));
return ParseLineMap(raw);
}
public string[] SchemaNames()
{
var raw = AamNative.TakeOwnedUtf8String(AamNative.aam_schema_names(Handle));
if (string.IsNullOrWhiteSpace(raw))
{
return Array.Empty<string>();
}
return raw.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
}
public string[] TypeNames()
{
var raw = AamNative.TakeOwnedUtf8String(AamNative.aam_type_names(Handle));
if (string.IsNullOrWhiteSpace(raw))
{
return Array.Empty<string>();
}
return raw.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
}
public void Dispose()
{
_handle?.Dispose();
_handle = null;
GC.SuppressFinalize(this);
}
private SafeAamHandle Handle
{
get
{
if (_handle is null || _handle.IsClosed || _handle.IsInvalid)
{
throw new ObjectDisposedException(nameof(AamDocument), "AamDocument is closed");
}
return _handle;
}
}
private void CheckResult(int result)
{
if (result == 0)
{
return;
}
var errPtr = AamNative.aam_last_error(Handle);
var message = AamNative.BorrowUtf8String(errPtr) ?? "Native operation failed";
throw new AamException(message);
}
private static Dictionary<string, string> ParseLineMap(string? raw)
{
var map = new Dictionary<string, string>(StringComparer.Ordinal);
if (string.IsNullOrWhiteSpace(raw))
{
return map;
}
var lines = raw.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
foreach (var line in lines)
{
var idx = line.IndexOf('=');
if (idx <= 0 || idx == line.Length - 1)
{
continue;
}
var k = line[..idx];
var v = line[(idx + 1)..];
map[k] = v;
}
return map;
}
}