using System.Runtime.InteropServices;
using System.Text;
namespace GeoSigmaDrawLib
{
public enum StreamError
{
STREAM_OK = 0,
STREAM_INVALID_HANDLE = 1,
STREAM_WRITE_FAILED = 2,
STREAM_ALREADY_CLOSED = 3,
STREAM_UNKNOWN_TYPE = 4
}
public enum StreamImportType
{
Points = 1,
XyzPoints = 2,
Curves = 3
}
public sealed class StreamImporter : IDisposable
{
private const string DllName = "GeoSigmaDraw.dll"; // 或实际 DLL 名
private long _handle;
private bool _disposed;
private nint pView;
private int importType;
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern long Stream_Open(IntPtr pView, int importType, out int outError);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern int Stream_Write(long handle, byte[] data, int size);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern int Stream_Close(long handle);
///
/// 创建流式表格导入器。Open 时即绑定视图与导入类型,后续 Write 会边解析边导入。
///
/// CSigmaView*(例如从 CreateView 得到的 IntPtr)
/// 点 / 散点 / 曲线
/// Open 失败时抛出
public StreamImporter(IntPtr pView, StreamImportType importType)
{
_handle = Stream_Open(pView, (int)importType, out int err);
if (_handle == 0 || err != (int)StreamError.STREAM_OK)
{
throw new InvalidOperationException($"Stream_Open failed: error={err}");
}
}
public StreamImporter(nint pView, int importType)
{
this.pView = pView;
this.importType = importType;
}
///
/// 写入一块 TSV 数据(UTF-8)。内部会边解析边导入,无需攒整表。
///
public void Write(byte[] buffer, int length)
{
ArgumentNullException.ThrowIfNull(buffer);
ArgumentOutOfRangeException.ThrowIfLessThan(length, 0, nameof(length));
ArgumentOutOfRangeException.ThrowIfGreaterThan(length, buffer.Length, nameof(length));
ObjectDisposedException.ThrowIf(_disposed, nameof(StreamImporter));
int ret = Stream_Write(_handle, buffer, length);
if (ret != (int)StreamError.STREAM_OK)
{
throw new InvalidOperationException($"Stream_Write failed: error={ret}");
}
}
public void Write(byte[] buffer)
{
Write(buffer, buffer.Length);
}
///
/// 写入一段 TSV 文本(按 GB2312 编码后写入)。
///
public void WriteString(string tsvText)
{
ArgumentNullException.ThrowIfNull(tsvText);
byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(tsvText);
Write(bytes, bytes.Length);
}
public void Close()
{
if (_disposed)
{
return;
}
if (_handle != 0)
{
_ = Stream_Close(_handle);
_handle = 0;
}
_disposed = true;
}
public void Dispose()
{
Close();
}
}
}