# 機能設計書 43-UTF8Encoding

## 概要

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

### 本機能の処理概要

UTF8Encodingクラスは、Unicode文字をUTF-8形式のバイト配列に変換（エンコード）、およびUTF-8形式のバイト配列をUnicode文字に変換（デコード）する機能を提供する。Encodingインターフェースを実装し、.NET FrameworkのSystem.Text.UTF8Encodingクラスと互換性のあるAPIを持つ。

**業務上の目的・背景**：UTF-8はインターネットで最も広く使用される文字エンコーディングであり、ASCII互換性を持ちながら全Unicode文字を表現可能。Webアプリケーション、JSONデータ、XMLファイルなど多くの場面でUTF-8が標準として採用されている。

**機能の利用シーン**：
- UTF-8テキストファイルの読み書き
- Web APIとのJSON通信
- XMLファイルの処理
- データベースとのUTF-8データ交換
- メール本文のエンコーディング

**主要な処理内容**：
1. Unicode文字列/文字配列からUTF-8バイト配列へのエンコード
2. UTF-8バイト配列からUnicode文字列/文字配列へのデコード
3. BOM（Byte Order Mark: EF BB BF）の出力制御
4. サロゲートペアの処理（4バイトエンコーディング）
5. 不正バイト列のフォールバック処理

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

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

## 関連画面

| 画面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以上、配列範囲内 |

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

| パラメータ名 | 型 | 必須 | 説明 | デフォルト値 |
|-------------|-----|-----|------|-------------|
| EncoderShouldEmitUTF8Identifier | Boolean | No | BOMを出力するか | False |
| ThrowOnInvalidBytes | Boolean | No | 不正バイト列で例外を投げるか | False |

## 出力仕様

### 出力データ

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

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

```
バイト数  ビット数  UTF-8表現
-----   ----    -----------------------------------
1        7      0vvvvvvv                    (ASCII互換: U+0000-U+007F)
2       11      110vvvvv 10vvvvvv           (U+0080-U+07FF)
3       16      1110vvvv 10vvvvvv 10vvvvvv  (U+0800-U+FFFF)
4       21      11110vvv 10vvvvvv 10vvvvvv 10vvvvvv (U+10000-U+10FFFF)
```

## 処理フロー

### 処理シーケンス

```
1. インスタンス生成
   └─ BOM出力設定、フォールバック設定の初期化
2. エンコード処理 (GetBytes)
   └─ GetByteCount: 必要バイト数計算
   └─ GetBytesCore: 文字→UTF-8バイト変換
       ├─ ASCII文字 (< 0x80): 1バイト出力
       ├─ 2バイト文字 (0x80-0x7FF): 2バイト出力
       ├─ BMP文字 (0x800-0xFFFF): 3バイト出力
       └─ サロゲートペア: 4バイト出力
3. デコード処理 (GetString/GetChars)
   └─ GetCharCount: 生成文字数計算
   └─ GetCharsCore: UTF-8バイト→文字変換
       ├─ 1バイト文字 (0xxxxxxx): ASCII直接変換
       ├─ 2バイト文字 (110xxxxx 10xxxxxx)
       ├─ 3バイト文字 (1110xxxx 10xxxxxx 10xxxxxx)
       └─ 4バイト文字 (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{処理種別}
    B -->|エンコード| C[GetByteCount計算]
    C --> D[バッファ確保]
    D --> E[GetBytesCore実行]
    E --> F{文字種別}
    F -->|ASCII| G[1バイト出力]
    F -->|2バイト文字| H[2バイト出力]
    F -->|BMP文字| I[3バイト出力]
    F -->|サロゲート| J{ペア完成?}
    J -->|Yes| K[4バイト出力]
    J -->|No| L[フォールバック]
    G --> M{次の文字?}
    H --> M
    I --> M
    K --> M
    L --> M
    M -->|Yes| F
    M -->|No| N[バイト配列返却]
    B -->|デコード| O[GetCharCount計算]
    O --> P[バッファ確保]
    P --> Q[GetCharsCore実行]
    Q --> R{バイト種別}
    R -->|1バイト| S[ASCII直接変換]
    R -->|マルチバイト開始| T[継続バイト読込]
    T --> U{シーケンス有効?}
    U -->|Yes| V[文字出力]
    U -->|No| W[フォールバック]
    S --> X{次のバイト?}
    V --> X
    W --> X
    X -->|Yes| R
    X -->|No| Y[文字列返却]
    N --> Z[終了]
    Y --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | BOM出力 | EmitUTF8Identifier=Trueの場合、GetPreambleでEF BB BFを返す | GetPreamble呼び出し時 |
| BR-002 | サロゲートペア処理 | HighSurrogate(D800-DBFF) + LowSurrogate(DC00-DFFF)を4バイトでエンコード | エンコード時 |
| BR-003 | 孤立サロゲート処理 | ペアになっていないサロゲートはフォールバック処理 | エンコード/デコード時 |
| BR-004 | 不正バイト列処理 | 無効なUTF-8シーケンスはDecoderFallbackで処理 | デコード時 |
| BR-005 | 最短形式強制 | オーバーロングエンコーディングは拒否（フォールバック） | デコード時 |
| BR-006 | コードページ | CodePageは常に65001を返す | CodePage取得時 |

### 計算ロジック

```
GetMaxByteCount(CharCount) = (CharCount + 1) * EncoderFallback.MaxCharCount * 3
GetMaxCharCount(ByteCount) = (ByteCount + 1) * DecoderFallback.MaxCharCount
```

サロゲートペア計算：
```
RealUnicodeValue = (HighSurrogate - 0xD800) * 0x400 + (LowSurrogate - 0xDC00) + 0x10000
```

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

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

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

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

## パフォーマンス要件

- ASCII文字のみのテキスト: 高速ループによる最適化処理
- 数KB程度のテキスト変換: 数ミリ秒以内
- 大規模テキスト（数MB）: GetEncoder/GetDecoderによるストリーム処理を推奨

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

- 不正なUTF-8シーケンスによる攻撃（オーバーロングエンコーディング等）を検出・拒否
- フォールバック設定により不正データの処理方法を制御可能
- サロゲートペアの不正な使用を検出

## 備考

- .NET FrameworkのUTF8Encodingと高い互換性を持つ
- VB6/VBAの内部文字表現はUTF-16のため、サロゲートペアの処理が必要
- ASCII文字の高速処理のため、ループアンローリング最適化を実装

---

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

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

### 推奨読解順序

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

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

**読解のコツ**:
- 37-47行目のコメントでUTF-8のエンコーディング規則を確認
- 63行目: コードページは65001で固定
- 70-77行目: マルチバイトシーケンス判定用の定数定義

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

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

**主要処理フロー**:
1. **276-296行目**: GetByteCountメソッド - エンコードに必要なバイト数計算
2. **310-330行目**: GetBytesメソッド - 文字→バイト配列変換
3. **346-361行目**: GetBytesExメソッド - 既存バッファへのエンコード
4. **374-380行目**: GetCharCountメソッド - デコードで生成される文字数計算
5. **395-404行目**: GetCharsメソッド - バイト→文字配列変換
6. **421-424行目**: GetCharsExメソッド - 既存バッファへのデコード
7. **439-459行目**: GetStringメソッド - バイト→文字列変換
8. **466-472行目**: GetPreambleメソッド - BOM取得（EF BB BF）

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

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

**主要処理フロー**:
- **650-945行目**: GetCharCountCore - デコード文字数計算（高速ループ最適化含む）
- **976-1367行目**: GetCharsCore - バイト→文字変換の実装
- **1464-1588行目**: GetByteCountCore - エンコードバイト数計算
- **1590-1822行目**: GetBytesCore - 文字→バイト変換の実装

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

```
UTF8Encoding
    │
    ├─ GetBytes(Chars)
    │      ├─ AsChars(): 文字配列変換
    │      ├─ ValidateGetBytes(): バリデーション
    │      ├─ GetByteCountCore(): バイト数計算
    │      │      ├─ ASCII高速ループ (< 0x80)
    │      │      ├─ 2バイト文字処理 (< 0x800)
    │      │      ├─ 3バイト文字処理 (< 0x10000)
    │      │      └─ サロゲートペア処理
    │      └─ GetBytesCore(): エンコード実行
    │             └─ FallbackUnknownChar(): フォールバック
    │
    ├─ GetString(Bytes)
    │      ├─ ValidateGetChars(): バリデーション
    │      ├─ GetCharCountCore(): 文字数計算
    │      │      ├─ ASCII高速ループ
    │      │      └─ マルチバイトシーケンス処理
    │      └─ GetCharsCore(): デコード実行
    │             ├─ 1バイト文字処理
    │             ├─ 2バイト文字処理
    │             ├─ 3バイト文字処理
    │             ├─ 4バイト文字処理（サロゲートペア生成）
    │             └─ FallbackCharacter(): フォールバック
    │
    ├─ GetEncoder()
    │      └─ UTF8Encoder.Init(Me)
    │
    └─ GetDecoder()
           └─ UTF8Decoder.Init(Me)
```

### データフロー図

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

文字列 ──────────────────▶ GetBytes ──────────────────▶ UTF-8バイト配列
  │                           │
  ├─ ASCII (< 0x80)           ├─ 1バイト (0xxxxxxx)
  ├─ U+0080-U+07FF            ├─ 2バイト (110xxxxx 10xxxxxx)
  ├─ U+0800-U+FFFF            ├─ 3バイト (1110xxxx 10xxxxxx 10xxxxxx)
  └─ サロゲートペア           └─ 4バイト (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)

UTF-8バイト配列 ──────────▶ GetString ─────────────────▶ 文字列
  │                           │
  ├─ 0xxxxxxx                 ├─ ASCII直接変換
  ├─ 110xxxxx 10xxxxxx        ├─ 2バイト→1文字
  ├─ 1110xxxx 10xxxxxx...     ├─ 3バイト→1文字
  └─ 11110xxx 10xxxxxx...     └─ 4バイト→サロゲートペア(2文字)

EmitUTF8Identifier ───────▶ GetPreamble ───────────────▶ BOM (EF BB BF)
                              または空配列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| UTF8Encoding.cls | `Source/CorLib/System.Text/UTF8Encoding.cls` | ソース | メインクラス定義（2036行） |
| UTF8Encoder.cls | `Source/CorLib/System.Text/UTF8Encoder.cls` | ソース | ストリーム用エンコーダ |
| UTF8Decoder.cls | `Source/CorLib/System.Text/UTF8Decoder.cls` | ソース | ストリーム用デコーダ |
| Encoding.cls | `Source/CorLib/System.Text/Encoding.cls` | ソース | インターフェース定義 |
| EncodingStatic.cls | `Source/CorLib/System.Text/EncodingStatic.cls` | ソース | UTF8プロパティ（145-151行目） |
| EncoderFallback.cls | `Source/CorLib/System.Text/EncoderFallback.cls` | ソース | エンコードフォールバック |
| DecoderFallback.cls | `Source/CorLib/System.Text/DecoderFallback.cls` | ソース | デコードフォールバック |
| EncoderReplacementFallback.cls | `Source/CorLib/System.Text/EncoderReplacementFallback.cls` | ソース | 置換フォールバック |
| DecoderExceptionFallback.cls | `Source/CorLib/System.Text/DecoderExceptionFallback.cls` | ソース | 例外フォールバック |
| Constructors.cls | `Source/CorLib/Constructors.cls` | ソース | NewUTF8Encodingファクトリメソッド |
