# 機能設計書 96-テキストバッファ

## 概要

本ドキュメントは、Windows Terminal / Console Host におけるテキストバッファ（TextBuffer）の機能設計を記述する。ターミナルのテキストデータを格納・管理するバッファ実装の構造と動作を解説する。

### 本機能の処理概要

TextBuffer クラスは、ターミナルに表示されるすべてのテキスト、属性（色、太字等）、カーソル位置を管理する中核データ構造である。循環バッファ方式でスクロールバック履歴を効率的に保持し、仮想メモリを活用して大規模バッファを低メモリコストで実現する。

**業務上の目的・背景**：ターミナルの画面に表示されるテキストと、スクロールバックで遡れる履歴テキストを統一的に管理する必要がある。TextBufferは数千行から数万行のテキストデータを効率的に保持し、高速な行アクセス、テキスト検索、ハイパーリンク管理、シェル統合マーク管理を提供する。

**機能の利用シーン**：VTアダプターからのテキスト書き込み、画面のスクロール、テキスト選択、検索、コピー操作、バッファのリフロー（ウィンドウリサイズ時）など、ターミナルのほぼすべての操作で参照・更新される。

**主要な処理内容**：
1. テキストとテキスト属性の行単位格納（ROW構造体）
2. 循環バッファによるスクロールバック管理（FirstRowインデックス回転）
3. 仮想メモリ（VirtualAlloc MEM_RESERVE/MEM_COMMIT）によるオンデマンドメモリ確保
4. カーソル管理（Cursor クラス）
5. 行幅・行レンディション管理（SingleWidth/DoubleWidth/DoubleHeightTop/Bottom）
6. テキスト検索（ICU正規表現対応）
7. ハイパーリンクID管理
8. シェル統合マーク（プロンプト/コマンド/出力の境界）管理
9. テキストコピー（プレーン/HTML/RTF/VTシーケンス付き）
10. バッファリフロー（Reflow）

**関連システム・外部連携**：Renderer にテキストデータを提供する。AdaptDispatch からテキスト書き込み・消去命令を受け取る。SCREEN_INFORMATION（Console Host）が所有する。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | TermControl（ターミナル表示） | 主画面 | テキストデータの格納と提供 |

## 機能種別

データ管理 / バッファ操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| screenBufferSize | til::size | Yes | バッファサイズ（幅x高さ） | 幅・高さが正の整数 |
| defaultAttributes | TextAttribute | Yes | デフォルトテキスト属性 | - |
| cursorSize | UINT | Yes | カーソルサイズ（パーセント） | 0-100 |
| isActiveBuffer | bool | Yes | アクティブバッファかどうか | - |
| renderer | Renderer* | No | レンダラーポインタ | - |

### 入力データソース

- AdaptDispatch / Console Host からのテキスト書き込み
- ユーザー入力によるカーソル移動

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| テキスト行データ | ROW | 行ごとのテキスト・属性・メタデータ |
| カーソル状態 | Cursor | カーソル位置・形状・可視状態 |
| 検索結果 | vector\<til::point_span\> | テキスト検索の一致箇所 |
| コピーテキスト | wstring/string | 選択範囲のプレーン/HTML/RTFテキスト |

### 出力先

Renderer（画面描画用データ提供）、クリップボード（コピー操作）

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ - バッファ初期化
   └─ VirtualAlloc(MEM_RESERVE)で仮想メモリ領域を確保
2. Replace/Insert/Write - テキスト書き込み
   └─ 対象ROWにテキストと属性を書き込み
3. IncrementCircularBuffer - 循環バッファ回転
   └─ _firstRowインデックスをインクリメント（上書き最古行）
4. ScrollRows - 行のスクロール
   └─ 指定範囲の行を上下に移動
5. Reflow - リフロー
   └─ バッファ幅変更時にテキストを再配置
6. SearchText - テキスト検索
   └─ ICU URegularExpressionによる正規表現検索
```

### フローチャート

```mermaid
flowchart TD
    A[テキスト書き込み要求] --> B[対象ROW取得]
    B --> C{ROWがコミット済み?}
    C -->|No| D[VirtualAlloc MEM_COMMIT]
    C -->|Yes| E[ROWにテキスト書き込み]
    D --> E
    E --> F{行末到達?}
    F -->|Yes| G{循環バッファ回転必要?}
    G -->|Yes| H[IncrementCircularBuffer]
    G -->|No| I[カーソル位置更新]
    H --> I
    F -->|No| I
    I --> J[レンダラーに更新通知]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-96-01 | 循環バッファ | _firstRowインデックスの回転でスクロールを実現（コピー不要） | スクロール時 |
| BR-96-02 | オンデマンドコミット | 128行ずつMEM_COMMITして実メモリ使用を最小化 | ROWアクセス時 |
| BR-96-03 | スクラッチパッドROW | 一時的なテキスト処理用の追加行を提供 | テキスト変換時 |
| BR-96-04 | グラフェムクラスタ | GraphemeNext/GraphemePrevでUnicode結合文字を正しく処理 | テキスト操作時 |
| BR-96-05 | ハイパーリンクID管理 | uint16_t IDでハイパーリンクを管理、URLとカスタムIDの双方向マップ | ハイパーリンク処理時 |

### 計算ロジック

- メモリレイアウト: ROW構造体 + パディング + _charsBuffer(_width * sizeof(wchar_t)) + パディング + _charOffsets((_width+1) * sizeof(uint16_t))
- コミット読み先行: _commitReadAheadRowCount = 128行

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| VirtualAlloc失敗 | メモリ不足 | MEM_RESERVE/MEM_COMMITの失敗 | 例外送出 |

### リトライ仕様

リトライは行わない。

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

該当なし。

## パフォーマンス要件

- 仮想メモリによりプライベートワーキングセットを最小化（80列で約4.1MB、120列で約5.6MB at 9001行）
- 循環バッファにより行スクロールがO(1)で完了（_firstRowの更新のみ）
- _lastMutationId によるフレーム間の変更検出最適化

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

- ハイパーリンクURLの管理において、不正なURLの検証は上位層の責務

## 備考

- textBuffer.hppのコメントに、ROW構造体の設計経緯（Therese Stowell 1990-1991年のオリジナル設計から発展）が記述されている
- スクラッチパッドROWは_height + 1番目の行として実装

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Row.hpp | `src/buffer/out/Row.hpp` | ROW構造体の定義。_charsBuffer, _charOffsets のレイアウト |
| 1-2 | TextAttribute.hpp | `src/buffer/out/TextAttribute.hpp` | テキスト属性（色、太字、下線等）の定義 |
| 1-3 | TextColor.h | `src/buffer/out/TextColor.h` | 色表現（デフォルト、インデックス、RGB） |
| 1-4 | cursor.h | `src/buffer/out/cursor.h` | カーソルクラス定義 |
| 1-5 | Marks.hpp | `src/buffer/out/Marks.hpp` | シェル統合マーク定義 |

**読解のコツ**: textBuffer.hppの冒頭コメント（22-47行目）にScreenBuffer全体のデータ構造概要図が記載されている。ROW→CHAR_ROW→ATTR_ROWの階層構造を理解することが重要。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | textBuffer.hpp | `src/buffer/out/textBuffer.hpp` | TextBufferクラス定義。全パブリックAPI一覧 |

**主要処理フロー**:
1. **71-75行目**: コンストラクタ（screenBufferSize, defaultAttributes, cursorSize, isActiveBuffer, renderer）
2. **88-91行目**: 行アクセスメソッド（GetScratchpadRow, GetRowByOffset, GetMutableRowByOffset）
3. **109-122行目**: テキスト書き込み（Replace, Insert, FillRect, Write, WriteLine）
4. **125行目**: IncrementCircularBuffer - 循環バッファ回転
5. **299行目**: Reflow - 静的メソッドによるバッファリフロー
6. **301-302行目**: SearchText - テキスト検索

#### Step 3: 仮想メモリ管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | textBuffer.cpp | `src/buffer/out/textBuffer.cpp` | TextBufferの実装。仮想メモリ管理（_reserve, _commit, _decommit） |

**主要処理フロー**:
- **355-406行目**: メモリレイアウトの説明コメント
- **394行目**: _commitReadAheadRowCount = 128

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

```
AdaptDispatch / Console Host API
    │
    ├─ TextBuffer::Replace() / Insert() / Write()
    │      ├─ _getRow(y)
    │      │      └─ _commit() (必要に応じてVirtualAlloc)
    │      └─ ROW::ReplaceText() / ROW::ReplaceAttributes()
    │
    ├─ TextBuffer::IncrementCircularBuffer()
    │      └─ _firstRow = (_firstRow + 1) % _height
    │
    ├─ TextBuffer::ScrollRows()
    │      └─ 行の移動（memmove相当）
    │
    ├─ TextBuffer::SearchText()
    │      └─ URegularExpression (ICU) による正規表現マッチ
    │
    └─ TextBuffer::Reflow() [static]
           └─ 旧バッファから新バッファへのテキスト再配置
```

### データフロー図

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

VTコマンド          ───▶ TextBuffer                ───▶ ROW配列
(Print/Write)              (テキスト書き込み)               (仮想メモリ上)
                           │                               │
カーソル移動        ───▶ Cursor                    ───▶ カーソル状態
                           │
選択/コピー         ───▶ GetPlainText/GenHTML/     ───▶ クリップボード
                           GenRTF
                           │
検索                ───▶ SearchText                ───▶ 一致箇所リスト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| textBuffer.hpp | `src/buffer/out/textBuffer.hpp` | ソース | TextBufferクラス定義 |
| textBuffer.cpp | `src/buffer/out/textBuffer.cpp` | ソース | TextBuffer実装 |
| Row.hpp | `src/buffer/out/Row.hpp` | ソース | ROW構造体定義 |
| Row.cpp | `src/buffer/out/Row.cpp` | ソース | ROW実装 |
| TextAttribute.hpp | `src/buffer/out/TextAttribute.hpp` | ソース | テキスト属性定義 |
| TextAttribute.cpp | `src/buffer/out/TextAttribute.cpp` | ソース | テキスト属性実装 |
| TextColor.h | `src/buffer/out/TextColor.h` | ソース | 色表現 |
| TextColor.cpp | `src/buffer/out/TextColor.cpp` | ソース | 色表現実装 |
| cursor.h | `src/buffer/out/cursor.h` | ソース | カーソル定義 |
| cursor.cpp | `src/buffer/out/cursor.cpp` | ソース | カーソル実装 |
| Marks.hpp | `src/buffer/out/Marks.hpp` | ソース | シェル統合マーク |
| search.h | `src/buffer/out/search.h` | ソース | 検索定義 |
| search.cpp | `src/buffer/out/search.cpp` | ソース | 検索実装 |
| ImageSlice.hpp | `src/buffer/out/ImageSlice.hpp` | ソース | Sixel画像スライス |
| UTextAdapter.h | `src/buffer/out/UTextAdapter.h` | ソース | ICU UText アダプター |
| LineRendition.hpp | `src/buffer/out/LineRendition.hpp` | ソース | 行レンディション定義 |
| DbcsAttribute.hpp | `src/buffer/out/DbcsAttribute.hpp` | ソース | DBCS属性 |
