# 機能設計書 76-バッファのエクスポート

## 概要

本ドキュメントは、Windows Terminalにおけるバッファエクスポート機能の設計を記述する。ターミナルバッファの内容をテキストファイルに保存する機能である。

### 本機能の処理概要

ExportBufferアクションは、アクティブなターミナルタブのバッファ全体の内容を読み取り、指定されたファイルパスまたはファイル選択ダイアログで選択された場所にテキストファイルとして保存する機能である。

**業務上の目的・背景**：ターミナルの出力内容をログとして保存したい場合や、コマンド実行結果を他のツールで分析したい場合に、バッファの内容をファイルとして永続化する必要がある。コピー&ペーストでは大量のバッファ内容を扱いにくいため、ファイル出力機能を提供する。

**機能の利用シーン**：デバッグログの保存、コマンド実行結果の記録、バッファ内容の共有、ビルドログの保存などに利用される。

**主要な処理内容**：
1. ExportBufferアクションの受信とパスパラメータの取得
2. パス未指定の場合、ファイル保存ダイアログの表示
3. ターミナルコントロールからバッファ全体の読み取り
4. UTF-8エンコーディングでファイルにアトミック書き込み

**関連システム・外部連携**：Win32 Shell API（ファイル保存ダイアログ）、ファイルシステムとの連携。

**権限による制御**：ファイルシステムへの書き込み権限が必要。昇格実行（管理者権限）時はUWP APIが使用不可のため、Shell32のファイルピッカーを直接使用する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleExportBufferによりバッファ内容をファイルに保存 |

## 機能種別

ファイル出力 / データエクスポート

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Path | hstring | No | 保存先ファイルパス（空の場合はダイアログ表示） | 環境変数を含む場合は自動展開 |

### 入力データソース

キーバインドまたはコマンドパレットからのアクション発行。ターミナルコントロールのバッファ内容。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| テキストファイル | .txt | バッファ全体のUTF-8テキストファイル |

### 出力先

ユーザー指定のファイルパスまたはファイル保存ダイアログで選択されたパス。デフォルトはダウンロードフォルダ。

## 処理フロー

### 処理シーケンス

```
1. ExportBufferアクション受信
   └─ _HandleExportBufferハンドラが呼び出される
2. ExportBufferArgs の取得
   └─ Path パラメータの確認
3. _ExportTab コルーチンの開始
   └─ アクティブタブとファイルパスを渡す
4. パスの決定
   ├─ パスが指定されている場合: 環境変数を展開
   └─ パスが空の場合: SaveFilePickerダイアログを表示
5. バッファ内容の読み取り
   └─ control.ReadEntireBuffer() でバッファ全体を取得
6. ファイル書き込み
   └─ til::io::write_utf8_string_to_file_atomic() でアトミック書き込み
```

### フローチャート

```mermaid
flowchart TD
    A[ExportBufferアクション受信] --> B[_HandleExportBuffer]
    B --> C{ExportBufferArgs取得成功?}
    C -->|Yes| D[_ExportTab with Path]
    C -->|No| E[_ExportTab with empty Path]
    D --> F{Path が空?}
    E --> F
    F -->|Yes| G[SaveFilePicker ダイアログ表示]
    F -->|No| H[環境変数展開]
    G --> I{ファイル選択された?}
    I -->|Yes| J[バッファ読み取り]
    I -->|No| K[処理終了]
    H --> J
    J --> L[ReadEntireBuffer]
    L --> M[UTF-8変換]
    M --> N[write_utf8_string_to_file_atomic]
    N --> O[処理完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-76-01 | デフォルト保存先 | ダウンロードフォルダをデフォルトの保存先とする | SaveFilePickerダイアログ使用時 |
| BR-76-02 | ファイル名デフォルト | タブのタイトルをデフォルトファイル名とする | SaveFilePickerダイアログ使用時 |
| BR-76-03 | ファイル形式 | デフォルトは.txtファイル。すべてのファイル形式も選択可能 | supportedFileTypes定義 |
| BR-76-04 | アトミック書き込み | ファイル書き込みはアトミック操作で行い、部分書き込みを防止 | write_utf8_string_to_file_atomic使用 |
| BR-76-05 | 環境変数展開 | パスに環境変数が含まれる場合は自動展開 | Path パラメータが指定された場合 |
| BR-76-06 | ダイアログGUID | 同一GUIDでダイアログを管理し、前回のパスを記憶 | clientGuidExportFile定数 |

### 計算ロジック

特になし。

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

### 操作別データベース影響一覧

本機能にデータベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル書き込み失敗 | 書き込み権限なし、ディスク容量不足等 | CATCH_LOG()で例外をログに記録 |
| - | ダイアログ表示失敗 | HWND未設定等 | CATCH_LOG()で例外をログに記録 |
| - | アクティブコントロールなし | タブにターミナルコントロールが存在しない場合 | 処理をスキップ |

### リトライ仕様

リトライは不要。ユーザーが再度アクションを実行する。

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

本機能にトランザクション処理はない。ただし、ファイル書き込みはアトミック操作（write_utf8_string_to_file_atomic）で行われ、不完全なファイルが生成されることを防止する。

## パフォーマンス要件

バッファの読み取りとファイル書き込みはコルーチン（safe_void_coroutine）内で実行される。大容量バッファの場合もUIスレッドをブロックしない。

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

バッファ内容にはパスワード等の機密情報が含まれる可能性がある。ファイル保存先はユーザーが明示的に選択する。UWP API ではなくShell32 APIを使用するのは、昇格実行時の互換性のため。

## 備考

- GH#11356: UWP APIは昇格実行時に動作しないため、Shell32のファイルピッカーを使用
- ファイル名にはタブタイトルが使用されるが、til::clean_filename()でファイル名として無効な文字を除去
- clientGuidExportFile（固定GUID）により、ファイルダイアログは前回のパスを記憶する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ActionArgs.h | `src/cascadia/TerminalSettingsModel/ActionArgs.h` | ExportBufferArgs のPathプロパティ |

**読解のコツ**: ExportBufferArgs.Path()が空文字の場合はファイル保存ダイアログが表示される。パス指定時は環境変数展開（ExpandEnvironmentStringsW）が行われる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | _HandleExportBuffer（1200-1222行目） |

**主要処理フロー**:
1. **1200-1201行目**: _HandleExportBufferハンドラ定義
2. **1203行目**: _senderOrFocusedTab でアクティブタブ取得
3. **1207行目**: ExportBufferArgsへのキャスト
4. **1209行目**: _ExportTab呼び出し（パスあり）
5. **1216行目**: _ExportTab呼び出し（パスなし、フォールバック）

#### Step 3: エクスポート実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TabManagement.cpp | `src/cascadia/TerminalApp/TabManagement.cpp` | _ExportTab（311-371行目） |

**主要処理フロー**:
- **315-318行目**: supportedFileTypes定義（.txt, *.*）
- **322行目**: clientGuidExportFile定数
- **326行目**: アクティブタブのTermControlを取得
- **330-352行目**: パスが空の場合のSaveFilePicker処理
- **354-361行目**: パスが指定されている場合の環境変数展開
- **365行目**: control.ReadEntireBuffer() でバッファ読み取り
- **366行目**: til::io::write_utf8_string_to_file_atomic() でファイル書き込み

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

```
TerminalPage::_HandleExportBuffer (AppActionHandlers.cpp:1200)
    │
    └─ TerminalPage::_ExportTab (TabManagement.cpp:311)
           │
           ├─ [Path空] SaveFilePicker()
           │      └─ Shell32 ファイルダイアログ
           │
           ├─ [Path指定] ExpandEnvironmentStringsW()
           │
           ├─ TermControl::ReadEntireBuffer()
           │      └─ バッファ全体のテキスト取得
           │
           └─ til::io::write_utf8_string_to_file_atomic()
                  └─ UTF-8エンコードでアトミック書き込み
```

### データフロー図

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

ExportBufferArgs ──────▶ _HandleExportBuffer
(Path)                        │
                              ▼
                        _ExportTab
                              │
                              ▼
TerminalBuffer ──────────▶ ReadEntireBuffer ──────▶ テキストデータ
                                                       │
                                                       ▼
                                              write_utf8_string_to_file_atomic
                                                       │
                                                       ▼
                                              .txt ファイル（UTF-8）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | ExportBufferアクションハンドラ |
| TabManagement.cpp | `src/cascadia/TerminalApp/TabManagement.cpp` | ソース | _ExportTab実装 |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ヘッダー | _ExportTab宣言（350行目） |
| ActionArgs.h | `src/cascadia/TerminalSettingsModel/ActionArgs.h` | ヘッダー | ExportBufferArgs定義 |
| ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | IDL | ExportBufferArgs WinRTインターフェース |
