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(); } } }