# 機能設計書 46-UnicodeEncoding

## 概要

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

### 本機能の処理概要

UnicodeEncodingクラスは、Unicode文字をUTF-16形式（1文字あたり2バイトまたは4バイト）のバイト配列に変換（エンコード）、およびUTF-16形式のバイト配列をUnicode文字に変換（デコード）する機能を提供する。ビッグエンディアン/リトルエンディアンの両方をサポートし、VB6/VBAの内部文字表現と同一のフォーマットである。

**業務上の目的・背景**：UTF-16はVB6/VBAおよびWindowsの内部文字表現として使用されるエンコーディング。文字列の内部処理、Windows APIとの連携、Javaとのデータ交換などで使用される。

**機能の利用シーン**：
- VB6/VBA文字列のバイト配列変換
- Windows APIとの文字列データ交換
- Unicodeテキストファイルの読み書き
- Javaシステムとのデータ連携（UTF-16BE）
- XMLファイルの処理

**主要な処理内容**：
1. Unicode文字（サロゲートペア含む）からUTF-16バイト配列へのエンコード
2. UTF-16バイト配列からUnicode文字（サロゲートペア含む）へのデコード
3. BOM（Byte Order Mark）の出力制御
4. ビッグエンディアン/リトルエンディアン切り替え
5. 高速ループ最適化によるパフォーマンス向上

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

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | Base64 Encoding | 参照 | テキストのエンコーディング処理 |
| 6 | Real-Time Decryption | 参照 | 暗号化/復号化時のテキスト変換 |
| 7 | File Encryption | 参照 | ファイル暗号化時のテキスト処理 |

## 機能種別

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

## 入力仕様

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

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| 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-16エンコードされたバイト配列（2バイト/文字） |
| GetChars戻り値 | Integer() | デコードされたUnicode文字配列 |
| GetString戻り値 | String | デコードされたUnicode文字列 |
| GetByteCount戻り値 | Long | エンコードに必要なバイト数 |
| GetCharCount戻り値 | Long | デコードで生成される文字数 |
| GetPreamble戻り値 | Byte() | BOM（LE: FF FE、BE: FE FF）または空配列 |

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

```
リトルエンディアン (CodePage 1200):
  文字 → [LowByte] [HighByte]
  BOM: FF FE

ビッグエンディアン (CodePage 1201):
  文字 → [HighByte] [LowByte]
  BOM: FE FF

サロゲートペア (U+10000-U+10FFFF):
  High Surrogate (D800-DBFF): 2バイト
  Low Surrogate (DC00-DFFF): 2バイト
  合計: 4バイト
```

## 処理フロー

### 処理シーケンス

```
1. インスタンス生成
   └─ エンディアン設定、BOM出力設定、フォールバック設定の初期化
2. エンコード処理 (GetBytes)
   └─ GetByteCount: 必要バイト数計算（文字数 × 2）
   └─ GetBytesCore: 文字→UTF-16バイト変換
       ├─ 高速ループ（連続非サロゲート文字）
       └─ サロゲートペア検証・出力
3. デコード処理 (GetString/GetChars)
   └─ GetCharCount: 生成文字数計算
   └─ GetCharsCore: UTF-16バイト→文字変換
       ├─ 高速ループ（連続非サロゲート文字）
       └─ サロゲートペア検証
```

### フローチャート

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

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 2バイト基本 | BMP文字（U+0000-U+FFFF、サロゲート範囲除く）は2バイトでエンコード | エンコード時 |
| BR-002 | サロゲートペア | High+Lowサロゲートは各2バイト（計4バイト）でエンコード | エンコード時 |
| BR-003 | サロゲート検証 | 孤立サロゲートはフォールバック処理 | エンコード/デコード時 |
| BR-004 | BOM出力 | mEmitBOM=Trueの場合、GetPreambleでBOMを返す | GetPreamble呼び出し時 |
| BR-005 | エンディアン制御 | mIsBigEndian設定によりバイト順序を制御 | エンコード/デコード時 |
| BR-006 | コードページ | LE=1200、BE=1201を返す | CodePage取得時 |

### 計算ロジック

```
GetMaxByteCount(CharCount) = (CharCount + 1) * 2
GetMaxCharCount(ByteCount) = (ByteCount / 2) + (ByteCount And 1) + 1
```

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

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

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

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

## パフォーマンス要件

- VB6/VBA内部表現と同一のため、リトルエンディアン時は非常に高速
- 高速ループ最適化により、連続する非サロゲート文字を効率的に処理
- 数KB程度のテキスト変換: 数ミリ秒以内

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

- 孤立サロゲートによる不正なUTF-16シーケンスはフォールバック処理で対応
- エンディアンの不一致によるデータ破損に注意
- BOMを使用してエンディアンを明示することを推奨

## 備考

- UTF-16はVB6/VBA、Windows、Javaの内部文字表現
- リトルエンディアンはWindows標準、ビッグエンディアンはJava標準
- .NET FrameworkのUnicodeEncodingと高い互換性を持つ

---

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

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

### 推奨読解順序

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

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

**読解のコツ**:
- 69行目: mIsBigEndian - エンディアン設定
- 70行目: mEmitBOM - BOM出力設定
- 71行目: mCodePage - コードページ（LE: 1200、BE: 1201）
- 72-77行目: mEncoderFallback/mDecoderFallback - フォールバック設定

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

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

**主要処理フロー**:
1. **299-314行目**: GetByteCountメソッド - エンコードに必要なバイト数計算
2. **328-350行目**: GetBytesメソッド - 文字→バイト配列変換
3. **367-387行目**: GetBytesExメソッド - 既存バッファへのエンコード
4. **399-405行目**: GetCharCountメソッド - デコードで生成される文字数計算
5. **418-428行目**: GetCharsメソッド - バイト→文字配列変換
6. **444-449行目**: GetCharsExメソッド - 既存バッファへのデコード
7. **461-481行目**: GetStringメソッド - バイト→文字列変換
8. **488-499行目**: GetPreambleメソッド - BOM取得（LE: FF FE、BE: FE FF）

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

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

**主要処理フロー**:
- **694-815行目**: GetByteCountCore - エンコードバイト数計算
  - 713-741行目: 高速ループ（FastLoop）で非サロゲート文字をスキップ
  - 742-776行目: サロゲートペアの検証と計算
- **817-1011行目**: GetBytesCore - 文字→バイト変換の実装
  - 839-862行目: 高速ループで非サロゲート文字を一括コピー
  - 863-904行目: サロゲートペアの処理
  - 905-990行目: エンディアン変換とバイト出力
- **1013-1125行目**: GetCharCountCore - デコード文字数計算
- **1127-1357行目**: GetCharsCore - バイト→文字変換の実装
  - 1155-1202行目: 高速ループで非サロゲート文字を一括コピー
  - 1203-1298行目: サロゲートペアの検証と出力

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

```
UnicodeEncoding
    │
    ├─ GetBytes(Chars)
    │      ├─ AsChars(): 文字配列変換
    │      ├─ ValidateGetBytes(): バリデーション
    │      ├─ GetByteCountCore(): バイト数計算
    │      │      ├─ FastLoop: 非サロゲート文字スキップ
    │      │      └─ サロゲートペア検証
    │      └─ GetBytesCore(): エンコード実行
    │             ├─ FastLoop: 一括コピー
    │             ├─ サロゲートペア処理
    │             └─ InsertEncoderUnknownChar(): フォールバック
    │
    ├─ GetString(Bytes)
    │      ├─ ValidateGetChars(): バリデーション
    │      ├─ GetCharCountCore(): 文字数計算
    │      │      ├─ FastLoop: 非サロゲート文字スキップ
    │      │      └─ サロゲートペア検証
    │      └─ GetCharsCore(): デコード実行
    │             ├─ FastLoop: 一括コピー
    │             ├─ サロゲートペア検証
    │             └─ InsertDecoderUnknownChars(): フォールバック
    │
    ├─ GetEncoder()
    │      └─ UnicodeEncoder.Init(Me)
    │
    └─ GetDecoder()
           └─ UnicodeDecoder.Init(Me)
```

### データフロー図

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

文字列 ──────────────────▶ GetBytes ──────────────────▶ UTF-16バイト配列
  │                           │                          (2バイト/文字)
  ├─ BMP文字                  ├─ FastLoop: 一括2バイト出力
  └─ サロゲートペア           └─ 各2バイト（計4バイト）出力

UTF-16バイト配列 ──────────▶ GetString ─────────────────▶ 文字列
  │                           │
  ├─ 非サロゲート範囲         ├─ FastLoop: 一括文字出力
  └─ サロゲートペア           └─ High+Lowとして出力

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

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| UnicodeEncoding.cls | `Source/CorLib/System.Text/UnicodeEncoding.cls` | ソース | メインクラス定義（1559行） |
| UnicodeEncoder.cls | `Source/CorLib/System.Text/UnicodeEncoder.cls` | ソース | ストリーム用エンコーダ |
| UnicodeDecoder.cls | `Source/CorLib/System.Text/UnicodeDecoder.cls` | ソース | ストリーム用デコーダ |
| Encoding.cls | `Source/CorLib/System.Text/Encoding.cls` | ソース | インターフェース定義 |
| EncodingStatic.cls | `Source/CorLib/System.Text/EncodingStatic.cls` | ソース | Unicode/BigEndianUnicodeプロパティ |
| Constructors.cls | `Source/CorLib/Constructors.cls` | ソース | NewUnicodeEncodingファクトリメソッド |
