# 機能設計書 45-UTF32Encoding

## 概要

本ドキュメントは、VBCorLibライブラリにおけるUTF-32エンコーディング機能「UTF32Encoding」クラスの機能設計について記述する。

### 本機能の処理概要

UTF32Encodingクラスは、Unicode文字をUTF-32形式（1文字あたり4バイト固定長）のバイト配列に変換（エンコード）、およびUTF-32形式のバイト配列をUnicode文字に変換（デコード）する機能を提供する。ビッグエンディアン/リトルエンディアンの両方をサポートする。

**業務上の目的・背景**：UTF-32は1文字が常に4バイトで表現される固定長エンコーディングであり、文字位置の計算が容易。内部処理やインデックス計算が必要な場合に有用だが、メモリ効率が低いためストレージや転送には適さない。

**機能の利用シーン**：
- 文字列の内部処理（文字位置計算が必要な場合）
- Unicode正規化処理
- テキスト解析処理
- レガシーシステムとの互換性

**主要な処理内容**：
1. Unicode文字（サロゲートペア含む）からUTF-32バイト配列へのエンコード
2. UTF-32バイト配列からUnicode文字（サロゲートペア含む）へのデコード
3. BOM（Byte Order Mark）の出力制御
4. ビッグエンディアン/リトルエンディアン切り替え

**関連システム・外部連携**：EncodingStaticクラスを通じて取得可能。UTF32Encoder/UTF32Decoderクラスによるストリーム処理をサポート。

**権限による制御**：本機能には権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は画面からの直接操作を持たない |

## 機能種別

データ変換処理 / テキストエンコーディング

## 入力仕様

### 入力パラメータ（エンコード処理）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Chars | Integer() または String | Yes | エンコード対象の文字配列/文字列 | 初期化済み配列または有効な文字列 |
| Index | Long | No | 開始インデックス（0ベース） | 有効な配列範囲内 |
| Count | Long | No | 処理文字数 | 0以上、配列範囲内 |

### 入力パラメータ（デコード処理）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Bytes | Byte() | Yes | デコード対象のバイト配列 | 初期化済み配列 |
| Index | Long | No | 開始インデックス（0ベース） | 有効な配列範囲内 |
| Count | Long | No | 処理バイト数 | 0以上、配列範囲内 |

### コンストラクタパラメータ

| パラメータ名 | 型 | 必須 | 説明 | デフォルト値 |
|-------------|-----|-----|------|-------------|
| BigEndian | Boolean | No | ビッグエンディアンを使用するか | False |
| ByteOrderMark | Boolean | No | BOMを出力するか | True |
| ThrowOnInvalidBytes | Boolean | No | 不正バイト列で例外を投げるか | False |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| GetBytes戻り値 | Byte() | UTF-32エンコードされたバイト配列（4バイト/文字） |
| GetChars戻り値 | Integer() | デコードされたUnicode文字配列 |
| GetString戻り値 | String | デコードされたUnicode文字列 |
| GetByteCount戻り値 | Long | エンコードに必要なバイト数 |
| GetCharCount戻り値 | Long | デコードで生成される文字数 |
| GetPreamble戻り値 | Byte() | BOM（LE: FF FE 00 00、BE: 00 00 FE FF）または空配列 |

### UTF-32エンコーディング規則

```
リトルエンディアン (CodePage 12000):
  文字 → [Byte0] [Byte1] [Byte2] [Byte3]
  BOM: FF FE 00 00

ビッグエンディアン (CodePage 12001):
  文字 → [Byte3] [Byte2] [Byte1] [Byte0]
  BOM: 00 00 FE FF

サロゲートペア:
  High Surrogate (D800-DBFF) + Low Surrogate (DC00-DFFF)
  → 単一の32ビット値 (U+10000-U+10FFFF)
```

## 処理フロー

### 処理シーケンス

```
1. インスタンス生成
   └─ エンディアン設定、BOM出力設定、フォールバック設定の初期化
2. エンコード処理 (GetBytes)
   └─ GetByteCount: 必要バイト数計算（文字数 × 4）
   └─ GetBytesCore: 文字→UTF-32バイト変換
       ├─ BMP文字 (U+0000-U+D7FF, U+E000-U+FFFF): 4バイト出力
       └─ サロゲートペア: ペアを結合して4バイト出力
3. デコード処理 (GetString/GetChars)
   └─ GetCharCount: 生成文字数計算
   └─ GetCharsCore: UTF-32バイト→文字変換
       ├─ BMP文字: 1文字出力
       └─ サロゲート範囲 (U+10000-U+10FFFF): ペアとして2文字出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{処理種別}
    B -->|エンコード| C[文字ループ開始]
    C --> D{サロゲート処理中?}
    D -->|No| E{High Surrogate?}
    E -->|Yes| F[LastCharに保存]
    E -->|No| G{BMP文字?}
    G -->|Yes| H[4バイト出力]
    G -->|No| I[フォールバック]
    D -->|Yes| J{Low Surrogate?}
    J -->|Yes| K[ペア結合して4バイト出力]
    J -->|No| L[High Surrogateをフォールバック]
    F --> M{次の文字?}
    H --> M
    I --> M
    K --> M
    L --> M
    M -->|Yes| C
    M -->|No| N[残りサロゲート処理]
    N --> O[バイト配列返却]
    B -->|デコード| P[4バイト読込]
    P --> Q{エンディアン変換}
    Q --> R{文字種別}
    R -->|BMP文字| S[1文字出力]
    R -->|サロゲート範囲| T[ペアとして2文字出力]
    R -->|無効| U[フォールバック]
    S --> V{次の4バイト?}
    T --> V
    U --> V
    V -->|Yes| P
    V -->|No| W[残りバイト処理]
    W --> X[文字列返却]
    O --> Y[終了]
    X --> Y
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 固定長エンコード | 全ての文字は4バイトでエンコードされる | エンコード時 |
| BR-002 | サロゲートペア結合 | High+Lowサロゲートを結合して単一の32ビット値に変換 | エンコード時 |
| BR-003 | サロゲートペア分解 | U+10000以上の値をHigh+Lowサロゲートペアに分解 | デコード時 |
| BR-004 | BOM出力 | mEmitBOM=Trueの場合、GetPreambleでBOMを返す | GetPreamble呼び出し時 |
| BR-005 | エンディアン制御 | mIsBigEndian設定によりバイト順序を制御 | エンコード/デコード時 |
| BR-006 | コードページ | LE=12000、BE=12001を返す | CodePage取得時 |

### 計算ロジック

```
GetMaxByteCount(CharCount) = (CharCount + 1) * EncoderFallback.MaxCharCount * 4
GetMaxCharCount(ByteCount) = ByteCount / 2 + 2 （サロゲートペア考慮）
```

サロゲートペア計算：
```
UTF32Char = (HighSurrogate And &H3FF) * &H400 + (LowSurrogate And &H3FF) + &H10000
HighSurrogate = ((UTF32Char - &H10000) / &H400) + &HD800
LowSurrogate = ((UTF32Char - &H10000) And &H3FF) + &HDC00
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentNullException | Bytes/Chars配列が未初期化 | 配列を初期化してから呼び出し |
| - | ArgumentOutOfRangeException | Index/Countが配列範囲外 | 有効な範囲を指定 |
| - | ArgumentOutOfRangeException | CharCount/ByteCountが負の値 | 0以上の値を指定 |
| - | EncoderFallbackException | 不正サロゲート（ExceptionFallback設定時） | フォールバック設定変更またはデータ修正 |
| - | DecoderFallbackException | 不正UTF-32値（ExceptionFallback設定時） | フォールバック設定変更またはデータ修正 |
| - | ArgumentException | 出力バッファが小さすぎる | 十分なサイズのバッファを確保 |
| - | InvalidOperationException | 読み取り専用インスタンスのフォールバック設定変更 | Cloneで書き込み可能なコピーを作成 |

### リトライ仕様

データ変換処理であるため、リトライは不要。

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

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

## パフォーマンス要件

- 固定長のため変換処理は比較的高速
- メモリ使用量はUTF-8の約4倍（ASCII文字の場合）
- 数KB程度のテキスト変換: 数ミリ秒以内

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

- 不正なUTF-32値（サロゲート範囲の値、U+10FFFF超過）はフォールバック処理で対応
- エンディアンの不一致によるデータ破損に注意
- BOMを使用してエンディアンを明示することを推奨

## 備考

- UTF-32はメモリ効率が低いため、ストレージや通信には推奨されない
- 文字位置計算が必要な内部処理には適している
- .NET FrameworkのUTF32Encodingと高い互換性を持つ

---

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

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

### 推奨読解順序

#### Step 1: データ構造とクラス定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | UTF32Encoding.cls | `Source/CorLib/System.Text/UTF32Encoding.cls` | クラス定義、プライベート変数（54-59行目） |

**読解のコツ**:
- 55行目: mIsBigEndian - エンディアン設定
- 56行目: mEmitBOM - BOM出力設定
- 57行目: mCodePage - コードページ（LE: 12000、BE: 12001）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | UTF32Encoding.cls | `Source/CorLib/System.Text/UTF32Encoding.cls` | 公開メソッド（GetBytes、GetChars、GetString等） |

**主要処理フロー**:
1. **252-267行目**: GetByteCountメソッド - エンコードに必要なバイト数計算
2. **279-302行目**: GetBytesメソッド - 文字→バイト配列変換
3. **321-339行目**: GetBytesExメソッド - 既存バッファへのエンコード
4. **349-354行目**: GetCharCountメソッド - デコードで生成される文字数計算
5. **364-373行目**: GetCharsメソッド - バイト→文字配列変換
6. **567-587行目**: GetStringメソッド - バイト→文字列変換
7. **519-529行目**: GetPreambleメソッド - BOM取得（LE: FF FE 00 00、BE: 00 00 FE FF）

#### Step 3: コア処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | UTF32Encoding.cls | `Source/CorLib/System.Text/UTF32Encoding.cls` | GetBytesCore/GetCharsCore（内部処理） |

**主要処理フロー**:
- **671-673行目**: GetByteCountCore - GetBytesCoreを使用してバイト数計算
- **675-787行目**: GetBytesCore - 文字→バイト変換の実装
  - 704-732行目: BMP文字（U+0000-U+D7FF、U+E000-U+FFFF）の処理
  - 728-729行目: High Surrogateの保存
  - 734-769行目: サロゲートペアの結合処理
- **848-850行目**: GetCharCountCore - GetCharsCoreを使用して文字数計算
- **852-981行目**: GetCharsCore - バイト→文字変換の実装
  - 880-904行目: 4バイト読込とエンディアン処理
  - 914-926行目: BMP文字の出力
  - 930-940行目: サロゲートペア範囲（U+10000-U+10FFFF）の分解

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

```
UTF32Encoding
    │
    ├─ GetBytes(Chars)
    │      ├─ AsChars(): 文字配列変換
    │      ├─ ValidateGetBytes(): バリデーション
    │      ├─ GetByteCountCore(): バイト数計算
    │      │      └─ GetBytesCore(NullBytes)
    │      └─ GetBytesCore(): エンコード実行
    │             ├─ BMP文字: 4バイト出力
    │             ├─ High Surrogate: 保存
    │             ├─ Low Surrogate: ペア結合→4バイト出力
    │             └─ InsertFallbackCharacters(): フォールバック
    │
    ├─ GetString(Bytes)
    │      ├─ ValidateGetChars(): バリデーション
    │      ├─ GetCharCountCore(): 文字数計算
    │      │      └─ GetCharsCore(NullChars)
    │      └─ GetCharsCore(): デコード実行
    │             ├─ SwapEndian(): エンディアン変換（BE時）
    │             ├─ BMP文字: 1文字出力
    │             ├─ サロゲート範囲: 2文字出力（H+L）
    │             └─ InsertDecoderFallback(): フォールバック
    │
    ├─ GetEncoder()
    │      └─ UTF32Encoder.Init(Me)
    │
    └─ GetDecoder()
           └─ UTF32Decoder.Init(Me)
```

### データフロー図

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

文字列 ──────────────────▶ GetBytes ──────────────────▶ UTF-32バイト配列
  │                           │                          (4バイト/文字)
  ├─ BMP文字                  ├─ 直接4バイト出力
  └─ サロゲートペア           └─ 結合して4バイト出力

UTF-32バイト配列 ──────────▶ GetString ─────────────────▶ 文字列
  │                           │
  ├─ BMP範囲 (< U+10000)      ├─ 1文字出力
  └─ サロゲート範囲           └─ ペア分解して2文字出力
       (U+10000-U+10FFFF)

mEmitBOM=True ────────────▶ GetPreamble ───────────────▶ BOM
  ├─ リトルエンディアン                                  FF FE 00 00
  └─ ビッグエンディアン                                  00 00 FE FF
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| UTF32Encoding.cls | `Source/CorLib/System.Text/UTF32Encoding.cls` | ソース | メインクラス定義（1179行） |
| UTF32Encoder.cls | `Source/CorLib/System.Text/UTF32Encoder.cls` | ソース | ストリーム用エンコーダ |
| UTF32Decoder.cls | `Source/CorLib/System.Text/UTF32Decoder.cls` | ソース | ストリーム用デコーダ |
| Encoding.cls | `Source/CorLib/System.Text/Encoding.cls` | ソース | インターフェース定義 |
| EncodingStatic.cls | `Source/CorLib/System.Text/EncodingStatic.cls` | ソース | UTF32プロパティ（158-164行目） |
| Constructors.cls | `Source/CorLib/Constructors.cls` | ソース | NewUTF32Encodingファクトリメソッド |
