/// <summary> /// 読み仮名変換時のコールバックメソッド /// </summary> /// <param name="reason">呼び出し要因</param> /// <param name="job_id">ジョブID</param> /// <param name="user_data">ユーザーデータ(KanaJobDataへのポインタ)</param> /// <returns>ゼロを返す</returns> private static int TextBufferCallback(AitalkCore.EventReason reason, int job_id, IntPtr user_data) { GCHandle gc_handle = GCHandle.FromIntPtr(user_data); KanaJobData job_data = gc_handle.Target as KanaJobData; if (job_data == null) { return(0); } // 変換できた分だけGetKana()で読み取ってjob_dataのバッファに格納する int buffer_capacity = job_data.BufferCapacity; byte[] buffer = new byte[buffer_capacity]; AitalkCore.Result result; int read_bytes; do { result = AitalkCore.GetKana(job_id, buffer, buffer_capacity, out read_bytes, out _); if (result != AitalkCore.Result.Success) { break; } job_data.Output.AddRange(new ArraySegment <byte>(buffer, 0, read_bytes)); }while ((buffer_capacity - 1) <= read_bytes); if (reason == AitalkCore.EventReason.TextBufferClose) { job_data.CloseEvent.Set(); } return(0); }
/// <summary> /// テキストを読み仮名に変換する /// </summary> /// <param name="text">テキスト</param> /// <param name="Timeout">タイムアウト[ms]。0以下はタイムアウト無しで待ち続ける。</param> /// <returns>読み仮名文字列</returns> public static string TextToKana(string text, int timeout = 0) { UpdateParameter(); // ShiftJISに変換する UnicodeToShiftJis(text, out byte[] shiftjis_bytes, out int[] shiftjis_positions); // コールバックメソッドとの同期オブジェクトを用意する KanaJobData job_data = new KanaJobData(); job_data.BufferCapacity = 0x1000; job_data.Output = new List <byte>(); job_data.CloseEvent = new EventWaitHandle(false, EventResetMode.ManualReset); GCHandle gc_handle = GCHandle.Alloc(job_data); try { // 変換を開始する AitalkCore.JobParam job_param; job_param.ModeInOut = AitalkCore.JobInOut.PlainToKana; job_param.UserData = GCHandle.ToIntPtr(gc_handle); AitalkCore.Result result; result = AitalkCore.TextToKana(out int job_id, ref job_param, shiftjis_bytes); if (result != AitalkCore.Result.Success) { throw new AitalkException($"仮名変換が開始できませんでした。[{string.Join(",", shiftjis_bytes)}]", result); } // 変換の終了を待つ // timeoutで与えられた時間だけ待つ bool respond; respond = job_data.CloseEvent.WaitOne((0 < timeout) ? timeout : -1); // 変換を終了する result = AitalkCore.CloseKana(job_id); if (respond == false) { throw new AitalkException("仮名変換がタイムアウトしました。"); } else if (result != AitalkCore.Result.Success) { throw new AitalkException("仮名変換が正常に終了しませんでした。", result); } } finally { gc_handle.Free(); } // 変換結果に含まれるIrq MARKのバイト位置を文字位置へ置き換える Encoding encoding = Encoding.GetEncoding(932); return(ReplaceIrqMark(encoding.GetString(job_data.Output.ToArray()), shiftjis_positions)); }