|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建流式表格导入器。Open 时即绑定视图与导入类型,后续 Write 会边解析边导入。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="pVeiw">CSigmaView*(例如从 CreateView 得到的 IntPtr)</param>
|
|
|
|
|
|
/// <param name="importType">点 / 散点 / 曲线</param>
|
|
|
|
|
|
/// <exception cref="InvalidOperationException">Open 失败时抛出</exception>
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 写入一块 TSV 数据(UTF-8)。内部会边解析边导入,无需攒整表。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 写入一段 TSV 文本(按 GB2312 编码后写入)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
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();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|