# 機能設計書 33-StringWriter

## 概要

本ドキュメントは、VBCorLibライブラリにおけるStringWriterクラスの機能設計について記述する。StringWriterは、文字列バッファへの書き込みを行うためのテキストライタークラスである。

### 本機能の処理概要

**業務上の目的・背景**：アプリケーション開発において、動的に文字列を構築する処理が必要となる場面は多い。StringWriterは、StreamWriterと同一のインターフェースで文字列バッファへの書き込みを可能にし、ファイル出力とメモリ上の文字列構築を統一的に扱えるようにする。内部でStringBuilderを使用することで効率的な文字列連結を実現する。

**機能の利用シーン**：動的な文字列生成処理、テスト時のモック出力として使用する場合、StreamWriterと同一インターフェースで処理を行いたい場合、複数の書き込み操作を経て文字列を構築する場合など、文字列バッファへの出力が必要なすべての場面で利用される。

**主要な処理内容**：
1. 値の書き込み（WriteValue）- フォーマット対応
2. 行単位の書き込み（WriteLine）
3. 文字配列の書き込み（WriteChars、WriteLineChars）
4. 結果文字列の取得（ToString）
5. StringBuilderの取得（GetStringBuilder）
6. ライターのクローズ処理（CloseWriter）

**関連システム・外部連携**：TextWriterインターフェースを実装しており、StreamWriterと同様のインターフェースで使用可能。内部でStringBuilderを使用。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は画面を持たないライブラリクラスである |

## 機能種別

データ書き込み処理（テキストI/O）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| sb | StringBuilder | No | 出力先のStringBuilder | Nothingの場合は新規作成 |
| Provider | IFormatProvider | No | 書式プロバイダ | Nothingの場合は現在のカルチャを使用 |
| Value | Variant | Yes | 書き込む値 | - |
| Args | Variant() | No | フォーマット引数 | - |
| Chars | Integer() | Yes | 書き込む文字配列 | 有効な配列であること |
| Index | Variant | No | 文字配列の開始位置 | 配列範囲内であること |
| Count | Variant | No | 書き込む文字数 | 配列範囲内であること |

### 入力データソース

プログラムから直接渡される値およびフォーマット文字列

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 結果文字列 | String | ToStringで返される構築された文字列 |
| StringBuilder | StringBuilder | GetStringBuilderで返される内部バッファ |

### 出力先

内部のStringBuilderオブジェクト

## 処理フロー

### 処理シーケンス

```
1. StringWriter初期化
   └─ StringBuilder（新規または指定）を内部バッファとして設定
2. WriteValue操作
   └─ 値を文字列に変換
   └─ フォーマット引数がある場合はフォーマット処理
   └─ StringBuilderに追加
3. WriteLine操作
   └─ WriteValueと同様の処理
   └─ 改行文字を追加
4. WriteChars操作
   └─ 文字配列をStringBuilderに追加
5. ToString
   └─ StringBuilderの内容を文字列として返す
```

### フローチャート

```mermaid
flowchart TD
    A[StringWriter生成] --> B{StringBuilder指定?}
    B -->|Yes| C[指定されたStringBuilderを使用]
    B -->|No| D[新規StringBuilderを作成]
    C --> E[書き込み操作]
    D --> E
    E -->|WriteValue| F{フォーマット引数?}
    E -->|WriteLine| G[WriteValue + 改行追加]
    E -->|WriteChars| H[文字配列を追加]
    F -->|Yes| I[AppendFormatArrayEx]
    F -->|No| J[AppendString]
    I --> K[StringBuilder更新]
    J --> K
    G --> K
    H --> K
    K --> L[ToString呼び出し時に文字列取得]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | デフォルト改行文字 | Environment.NewLine（通常はCR-LF）を使用 | 初期化時 |
| BR-002 | NewLineカスタマイズ | NewLineプロパティで改行文字を変更可能 | 任意 |
| BR-003 | フォーマットプロバイダ | デフォルトはCurrentCultureを使用 | WriteValue時 |
| BR-004 | エンコーディング | UnicodeEncoding固定 | Encodingプロパティ参照時 |

### 計算ロジック

特になし

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ObjectDisposed_WriterClosed | ObjectDisposedException | ライターが閉じている状態でメソッド呼び出し | ライターを再度生成する |

### リトライ仕様

リトライ処理は実装されていない。

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

本機能はトランザクション管理を行わない。

## パフォーマンス要件

- StringBuilderを使用することで効率的な文字列連結を実現
- Flushメソッドは何も行わない（データは直接StringBuilderに書き込まれるため）

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

- 書き込みデータの内容に関する検証は行わない
- 機密データを含む場合は呼び出し元で適切な管理が必要

## 備考

- TextWriterインターフェースを実装しているため、多態的な利用が可能
- StreamWriterとの互換性を意識した設計
- GetStringBuilderで内部バッファに直接アクセス可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | StringWriter.cls | `Source/CorLib/System.IO/StringWriter.cls` | 48-52行目のプライベート変数宣言を確認 |

**読解のコツ**: mOutput（StringBuilder）、mProvider（フォーマットプロバイダ）、mEncoding（エンコーディング）、mNewLine（改行文字）が主要な状態変数。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | StringWriter.cls | `Source/CorLib/System.IO/StringWriter.cls` | 217-224行目のClass_InitializeとInitを確認 |

**主要処理フロー**:
1. **217-219行目**: Class_InitializeでmNewLineにEnvironment.NewLineを設定
2. **221-224行目**: InitでStringBuilderとFormatProviderを設定

#### Step 3: 書き込み処理の核心を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | StringWriter.cls | `Source/CorLib/System.IO/StringWriter.cls` | 137-141行目のWriteValueメソッド |
| 3-2 | StringWriter.cls | `Source/CorLib/System.IO/StringWriter.cls` | 259-270行目のWriteCoreメソッド |
| 3-3 | StringWriter.cls | `Source/CorLib/System.IO/StringWriter.cls` | 167-171行目のWriteLineメソッド |

**主要処理フロー**:
- **139-140行目**: ParamArrayの引数をスワップして内部メソッドに渡す
- **263行目**: Object.ToStringで値を文字列に変換
- **265-268行目**: フォーマット引数の有無で分岐処理

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

```
StringWriter
    │
    ├─ Init (コンストラクタ)
    │      └─ StringBuilder設定
    │
    ├─ WriteValue
    │      └─ WriteCore
    │             ├─ Object.ToString
    │             └─ StringBuilder.AppendString / AppendFormatArrayEx
    │
    ├─ WriteLine
    │      └─ WriteLineCore
    │             ├─ WriteCore
    │             └─ StringBuilder.AppendString (NewLine)
    │
    ├─ WriteChars
    │      └─ StringBuilder.Append
    │
    ├─ WriteLineChars
    │      ├─ WriteChars
    │      └─ StringBuilder.AppendString (NewLine)
    │
    ├─ GetStringBuilder
    │      └─ mOutput を返す
    │
    ├─ ToString
    │      └─ mOutput.ToString
    │
    └─ CloseWriter
           └─ mIsClosed = True
```

### データフロー図

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

Value ─────────▶ WriteValue
                     │
                     ▼
              文字列変換・フォーマット
                     │
                     ▼
              StringBuilder.Append
                     │
                     ▼
              ToString ─────────────▶ 結果文字列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| StringWriter.cls | `Source/CorLib/System.IO/StringWriter.cls` | ソース | StringWriterクラス本体 |
| TextWriter.cls | `Source/CorLib/System.IO/TextWriter.cls` | ソース | 実装インターフェース |
| StreamWriter.cls | `Source/CorLib/System.IO/StreamWriter.cls` | ソース | 関連クラス（同インターフェース） |
| StringBuilder.cls | `Source/CorLib/System/StringBuilder.cls` | ソース | 内部バッファ |
