# 機能設計書 99-入力バッファ管理

## 概要

本ドキュメントは、Console Host における入力バッファ管理（InputBuffer）の機能設計を記述する。コンソール入力バッファの管理（キー入力、マウス入力、IME入力）の構造と動作を解説する。

### 本機能の処理概要

InputBuffer クラスは、Console Host のコンソール入力バッファを管理する中核コンポーネントである。キーボード入力、マウス入力、フォーカスイベントを INPUT_RECORD 形式で格納し、ReadConsole/ReadConsoleInput API 呼び出しに応じてイベントを提供する。VTモードが有効な場合は TerminalInput を使用してVTシーケンスへの変換も行う。

**業務上の目的・背景**：Console APIを使用するCUIアプリケーション（cmd.exe、PowerShell等）は、ReadConsole/ReadConsoleInput APIを通じて入力を受け取る。InputBufferはこれらのAPIのバックエンドとして、入力イベントの蓄積、読み出し、ピーク、フラッシュ機能を提供する。Unicode/ANSI両方のAPIをサポートし、DBCSの部分バイト処理も行う。

**機能の利用シーン**：CUIアプリケーションがReadConsole/ReadConsoleInputで入力を待機している場合に、InputBufferに蓄積されたイベントを提供する。入力がない場合はWaitQueueで読み取り側スレッドをブロックする。

**主要な処理内容**：
1. INPUT_RECORD の格納・読み出し（dequeベースのFIFOキュー）
2. 文字列指向API（Consume/Cache）とINPUT_RECORD指向APIの双方をサポート
3. Unicode/ANSI変換（WideCharToMultiByte）
4. DBCS部分バイトシーケンスの管理
5. イベント結合（連続する同一キーイベントの結合）
6. 待機キュー管理（データ到着時の読み取り側ウェイクアップ）
7. VTモード時のTerminalInput統合
8. フォーカスイベント・マウスイベントの書き込み

**関連システム・外部連携**：Console API（ReadConsole/WriteConsole等）の入力側バックエンド。TerminalInput と連携してVTシーケンスへの変換を行う。

**権限による制御**：InputMode フラグ（ENABLE_LINE_INPUT, ENABLE_PROCESSED_INPUT, ENABLE_ECHO_INPUT, ENABLE_MOUSE_INPUT, ENABLE_VIRTUAL_TERMINAL_INPUT等）による入力処理モード制御。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | conhost.exe ウィンドウ | 主画面 | キーボード・マウス入力の受け付け |

## 機能種別

データ管理 / 入力バッファリング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| inEvent | INPUT_RECORD | Yes | 書き込む入力イベント | - |
| inEvents | span\<const INPUT_RECORD\> | Yes | 書き込む入力イベント配列 | - |
| text | wstring_view | Yes | 書き込むテキスト（WriteString用） | - |
| AmountToRead | size_t | Yes | 読み出しイベント数 | 正の整数 |
| Peek | bool | Yes | ピーク読み出しかどうか | - |
| Unicode | bool | Yes | Unicode APIかどうか | - |

### 入力データソース

- Windowsメッセージループからのキーボード・マウスイベント
- VtInputThread からのVT入力変換結果
- Console API（WriteConsoleInput）からの直接書き込み

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| OutEvents | InputEventQueue | 読み出された入力イベント |
| 文字データ | span\<char\>/wstring_view | 文字列指向APIでの出力 |

### 出力先

Console API応答（ReadConsole/ReadConsoleInput）

## 処理フロー

### 処理シーケンス

```
1. Write(inEvent) / Write(inEvents) - 入力イベント書き込み
   └─ _CoalesceEventでイベント結合を試行
   └─ _storageデキューに追加
   └─ 待機中リーダーのウェイクアップ
2. Read(OutEvents, ...) - 入力イベント読み出し
   └─ WaitForData時はキューが空ならブロック
   └─ Unicode/ANSI変換
   └─ Peekの場合はイベントを消費しない
3. Consume() / ConsumeCached() - 文字列指向読み出し
   └─ Unicode/ANSI変換付きの文字列転送
4. Flush() / FlushAllButKeys() - バッファフラッシュ
   └─ 全イベントまたはキー以外のイベントを削除
```

### フローチャート

```mermaid
flowchart TD
    A[入力イベント到着] --> B{VTモード?}
    B -->|Yes| C[TerminalInput変換]
    B -->|No| D[_storage.push_back]
    C --> E{変換成功?}
    E -->|Yes| F[VTシーケンスをキャッシュ]
    E -->|No| D
    D --> G[_CoalesceEvent試行]
    G --> H[_wakeupReadersOnExit]
    H --> I{リーダー待機中?}
    I -->|Yes| J[リーダーウェイクアップ]
    I -->|No| K[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-99-01 | デフォルト入力モード | ENABLE_LINE_INPUT \| ENABLE_PROCESSED_INPUT \| ENABLE_ECHO_INPUT \| ENABLE_MOUSE_INPUT | InputBuffer作成時 |
| BR-99-02 | イベント結合 | 連続する同一キーの KEY_EVENT は repeat count を加算して結合 | Write時 |
| BR-99-03 | 読み出しモード切替 | StringA/StringW/InputEventsA/InputEventsW の4モード間の切替時にキャッシュをリセット | モード切替時 |
| BR-99-04 | DBCS部分バイト管理 | ANSI APIでDBCSの後半バイトが残った場合にキャッシュ | ANSI文字列読み出し時 |

### 計算ロジック

特記なし。

## データベース操作仕様

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERROR_INSUFFICIENT_BUFFER | バッファ不足 | ANSI変換でバッファが不足 | キャッシュに変換結果を保存し次回提供 |

### リトライ仕様

リトライは行わない。未変換分はキャッシュして次回のConsume呼び出しで提供する。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- dequeベースのFIFOキューで効率的な先頭・末尾操作
- _wakeupReadersOnExit() の scope_exit パターンで確実なリーダーウェイクアップ

## セキュリティ考慮事項

- InputMode フラグによるモード制御（プロセスごとに設定可能）

## 備考

- INPUT_BUFFER_DEFAULT_INPUT_MODE は (ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT)
- ConsoleObjectHeader を継承しており、Console API のオブジェクト管理に統合されている

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | inputBuffer.hpp | `src/host/inputBuffer.hpp` | InputBufferクラス定義。ReadingMode列挙体、_storageデキュー |

**読解のコツ**: InputBuffer は ConsoleObjectHeader を継承しており、Console API のオブジェクト管理フレームワークの一部である。_storage (std::deque\<INPUT_RECORD\>) がメインのイベントキュー。

**主要処理フロー**:
1. **20-21行目**: InputBuffer は ConsoleObjectHeader 継承
2. **23行目**: InputMode (DWORD) - 入力モードフラグ
3. **24行目**: WaitQueue (ConsoleWaitQueue) - 読み取り待機キュー
4. **67-68行目**: ReadingMode列挙体（StringA/StringW/InputEventsA/InputEventsW）
5. **82行目**: _storage (std::deque\<INPUT_RECORD\>) - メインキュー
6. **85行目**: _termInput (TerminalInput) - VT入力ハンドラ

#### Step 2: イベント書き込み処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | inputBuffer.cpp | `src/host/inputBuffer.cpp` | InputBuffer の実装 |

**主要処理フロー**:
- **14行目**: INPUT_BUFFER_DEFAULT_INPUT_MODE定義
- **26-29行目**: コンストラクタ。InputMode初期化
- **38-80行目**: Consume() - 文字列指向の読み出し処理、Unicode/ANSI変換

### プログラム呼び出し階層図

```
キーボード/マウスイベント → HandleGenericKeyEvent()
    │
    └─ InputBuffer::Write(INPUT_RECORD)
           ├─ _CoalesceEvent() → イベント結合試行
           ├─ _WriteBuffer()   → _storageへの書き込み
           └─ _wakeupReadersOnExit()
                  └─ WaitQueue::WakeUpReadersWaitingForData()

ReadConsole API → InputBuffer::Consume()
    │
    ├─ ConsumeCached() → キャッシュからの読み出し
    └─ WideCharToMultiByte() → ANSI変換（非Unicode時）

ReadConsoleInput API → InputBuffer::Read()
    │
    ├─ ConsumeCached() → キャッシュからの読み出し
    └─ _storage から INPUT_RECORD 取得
```

### データフロー図

```
[入力]                    [処理]                          [出力]

キーイベント         ───▶ InputBuffer::Write        ───▶ _storage (deque)
(INPUT_RECORD)             (イベント結合・格納)             │
                                                         Read/Consume
マウスイベント       ───▶ WriteMouseEvent                  │
(til::point + button)      (TerminalInput変換含む)   ───▶ ReadConsole応答
                                                         (Unicode/ANSI)
VT入力              ───▶ TerminalInput::HandleKey
(VTシーケンス)             (INPUT_RECORD生成)        ───▶ ReadConsoleInput応答
                                                         (INPUT_RECORD配列)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| inputBuffer.hpp | `src/host/inputBuffer.hpp` | ソース | InputBufferクラス定義 |
| inputBuffer.cpp | `src/host/inputBuffer.cpp` | ソース | InputBuffer実装 |
| input.h | `src/host/input.h` | ソース | 入力関連定数・関数宣言 |
| input.cpp | `src/host/input.cpp` | ソース | 入力処理実装 |
| inputReadHandleData.h | `src/host/inputReadHandleData.h` | ソース | 読み取りハンドルデータ |
| readData.hpp | `src/host/readData.hpp` | ソース | 読み取りデータ基底クラス |
| readDataCooked.hpp | `src/host/readDataCooked.hpp` | ソース | 加工済み読み取り |
| readDataRaw.hpp | `src/host/readDataRaw.hpp` | ソース | 生読み取り |
| readDataDirect.cpp | `src/host/readDataDirect.cpp` | ソース | ダイレクト読み取り |
| terminalInput.hpp | `src/terminal/input/terminalInput.hpp` | ソース | VT入力変換 |
