/// Copyright (c) 2023 Xiaomi Corporation (authors: Fangjun Kuang) /// Copyright (c) 2023 by manyeyes /// Copyright (c) 2024.5 by 东风破 using System; using System.Runtime.InteropServices; using System.Text; namespace SherpaOnnx { public class OnlineRecognizerResult { public OnlineRecognizerResult(IntPtr handle) { Impl impl = (Impl)Marshal.PtrToStructure(handle, typeof(Impl)); // PtrToStringUTF8() requires .net standard 2.1 // _text = Marshal.PtrToStringUTF8(impl.Text); int length = 0; unsafe { byte* buffer = (byte*)impl.Text; while (*buffer != 0) { ++buffer; length += 1; } } byte[] stringBuffer = new byte[length]; Marshal.Copy(impl.Text, stringBuffer, 0, length); _text = Encoding.UTF8.GetString(stringBuffer); _tokens = new String[impl.Count]; unsafe { byte* buf = (byte*)impl.Tokens; for (int i = 0; i < impl.Count; i++) { length = 0; byte* start = buf; while (*buf != 0) { ++buf; length += 1; } ++buf; stringBuffer = new byte[length]; fixed (byte* pTarget = stringBuffer) { for (int k = 0; k < length; k++) { pTarget[k] = start[k]; } } _tokens[i] = Encoding.UTF8.GetString(stringBuffer); } } unsafe { float* t = (float*)impl.Timestamps; if (t != null) { _timestamps = new float[impl.Count]; fixed (float* pTarget = _timestamps) { for (int i = 0; i < impl.Count; i++) { pTarget[i] = t[i]; } } } else { _timestamps = new float[] {}; } } } [StructLayout(LayoutKind.Sequential)] struct Impl { public IntPtr Text; public IntPtr Tokens; public IntPtr TokensArr; public IntPtr Timestamps; public int Count; } private String _text; public String Text => _text; private String[] _tokens; public String[] Tokens => _tokens; private float[] _timestamps; public float[] Timestamps => _timestamps; } }