# 機能設計書 86-ResourceReader

## 概要

本ドキュメントは、VBCorLibライブラリにおけるResourceReader（リソースリーダー）機能の設計を記述する。

### 本機能の処理概要

ResourceReaderは、.RES形式のリソースファイルを読み込み、リソースを列挙するための機能を提供するクラスである。バイナリリソースファイルを解析し、文字列、アイコン、カーソル、ビットマップなどのリソースを取得する。

**業務上の目的・背景**：Windows標準の.RES形式のリソースファイルを読み込み、その内容をVB6アプリケーションから利用可能にする。本機能は.NET FrameworkのSystem.Resources.ResourceReaderと互換性のあるAPIを提供する。

**機能の利用シーン**：
- .RESファイルからのリソース読み込み
- ResourceManagerへのリソース提供
- ResourceSetへのリソース提供
- リソースの列挙と取得

**主要な処理内容**：
1. .RESファイルの検証と読み込み
2. リソースヘッダーの解析
3. リソースデータのデコード
4. リソースの列挙（IDictionaryEnumerator）
5. カスタムデコーダーの追加

**関連システム・外部連携**：
- BinaryReader（バイナリファイル読み込み）
- IResourceDecoder（リソースデコーダーインターフェース）
- 各種デコーダー（StringResourceDecoder, BitMapResourceDecoder等）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | - | - | ResourceReaderはライブラリ機能として他のアプリケーションから利用される |

## 機能種別

データアクセス / ファイル読み込み

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Source | Variant | Yes | ファイルパス、バイト配列、またはStreamオブジェクト | 有効なソースであること |
| DecoderToAdd | IResourceDecoder | No | カスタムデコーダー | Nothingでないこと |

### 入力データソース

- .RESファイル（ファイルパス指定）
- バイト配列（メモリ上の.RESデータ）
- Streamオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DictionaryEntry | DictionaryEntry | キー（ResourceKey）と値（リソースデータ）のペア |
| ResourceKey | ResourceKey | リソース識別情報（名前、タイプ、言語ID） |
| ResourceValue | Variant | デコードされたリソース値 |

### 出力先

呼び出し元アプリケーションへの戻り値（列挙子経由）

## 処理フロー

### 処理シーケンス

```
1. ソースの検証
   └─ ファイル/バイト配列/Streamの判定
2. .RESファイル形式の検証
   └─ ヘッダーサイズ、DataSize、HeaderSizeのチェック
3. リソースの読み込み
   └─ 各リソースエントリの解析
4. リソースのデコード
   └─ 適切なデコーダーによる変換
5. リソースの返却
   └─ DictionaryEntry形式で提供
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{ソースタイプ判定}
    B -->|String| C[FileStream作成]
    B -->|Byte配列| D[MemoryStream作成]
    B -->|Stream| E[そのまま使用]
    C --> F[BinaryReader作成]
    D --> F
    E --> F
    F --> G[.RESファイル検証]
    G -->|無効| H[IOException]
    G -->|有効| I[リソース読み込みループ]
    I --> J{次のリソースあり?}
    J -->|Yes| K[ヘッダー解析]
    K --> L[データ読み込み]
    L --> M{デコーダーあり?}
    M -->|Yes| N[デコード処理]
    M -->|No| O[バイト配列として保存]
    N --> P[エントリ追加]
    O --> P
    P --> J
    J -->|No| Q[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-86-01 | ファイル形式検証 | 先頭32バイトが空ヘッダーであること | 初期化時 |
| BR-86-02 | デコーダー優先 | 登録済みデコーダーがある場合はそれを使用 | リソース読み込み時 |
| BR-86-03 | バイト配列フォールバック | デコーダーがない場合はバイト配列として返す | リソース読み込み時 |
| BR-86-04 | DWordアライメント | データはDWord（4バイト）境界でアライメント | ファイル読み込み時 |

### 計算ロジック

**DWordアライメント計算**:
```vb
If (CurrentPosition Mod 4) <> 0 Then
    SeekPosition 4 - (CurrentPosition Mod 4), FromCurrent
End If
```

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

本機能はデータベースを直接操作しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IOException | 無効なファイル形式 | .RESファイル形式でない | 正しいファイル形式を使用する |
| InvalidOperationException | リーダークローズ | クローズ後のアクセス | CloseReader前にアクセスする |
| ArgumentNullException | Null引数 | DecoderToAddがNothing | 有効なデコーダーを渡す |
| ArgumentException | 無効な引数 | 無効なSourceタイプ | サポートされる型を使用する |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- リソースは列挙時に一括読み込みされる（遅延読み込みではない）

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

- 外部ファイルを読み込むため、信頼できないソースからのファイルに注意

## 備考

- .NET FrameworkのSystem.Resources.ResourceReaderと互換性のあるAPI
- IResourceReaderインターフェースを実装
- 標準デコーダー：String, BitMap, Icon, IconGroup, Cursor, CursorGroup
- AddDecoderでカスタムデコーダーを追加可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ResourceReader.cls | `Source/CorLib/System.Resources/ResourceReader.cls` | ResourceHeader構造体とメンバ変数を確認 |

**主要データ構造（58-68行目）**:
```vb
Private Type ResourceHeader
    DataSize As Long
    HeaderSize As Long
    ResourceType As Variant
    ResourceName As Variant
    DataVersion As Long
    MemoryFlags As Integer
    LanguageID As Integer
    Version As Long
    Characteristics As Long
End Type
```

#### Step 2: 初期化処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ResourceReader.cls | `Source/CorLib/System.Resources/ResourceReader.cls` | Init, GetStream, VerifyResourceFile |

**主要処理フロー**:
- **192-195行目**: Init - BinaryReader作成とファイル検証
- **224-258行目**: GetStream - ソースタイプに応じたStream作成
- **322-342行目**: VerifyResourceFile - .RESファイル形式の検証

#### Step 3: リソース読み込み処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ResourceReader.cls | `Source/CorLib/System.Resources/ResourceReader.cls` | LoadResources, GetNextResource, GetNextResourceHeader |

**主要処理フロー**:
- **307-320行目**: LoadResources - リソースの一括読み込み
- **266-295行目**: GetNextResource - 次のリソースを取得
- **395-419行目**: GetNextResourceHeader - ヘッダー情報の解析

#### Step 4: デコーダーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ResourceReader.cls | `Source/CorLib/System.Resources/ResourceReader.cls` | AddDecoder, Class_Initialize |

**主要処理フロー**:
- **90-105行目**: AddDecoder - カスタムデコーダーの追加
- **197-207行目**: Class_Initialize - 標準デコーダーの登録

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

```
ResourceReader
    │
    ├─ 初期化
    │      ├─ Init
    │      │      ├─ GetStream
    │      │      │      ├─ FileStream (ファイルパス)
    │      │      │      ├─ MemoryStream (バイト配列)
    │      │      │      └─ そのまま (Stream)
    │      │      └─ VerifyResourceFile
    │      │
    │      └─ Class_Initialize
    │             └─ AddDecoder (標準デコーダー登録)
    │
    ├─ リソース読み込み
    │      ├─ GetEnumerator
    │      │      └─ LoadResources
    │      │             └─ GetNextResource
    │      │                    ├─ GetNextResourceHeader
    │      │                    │      ├─ GetOrdinalOrName
    │      │                    │      └─ DWordAlignStreamPosition
    │      │                    ├─ IResourceDecoder.Decode
    │      │                    └─ IResourceDecoder.GetResource
    │      │
    │      └─ NewEnum
    │             └─ GetEnumerator
    │
    └─ クリーンアップ
           └─ CloseReader
```

### データフロー図

```
[入力]                    [ResourceReader]              [出力]

.RES ファイル ───┐              │
                 │              ▼
バイト配列 ──────┼──▶ BinaryReader ──▶ ResourceHeader解析
                 │              │              │
Stream ──────────┘              ▼              ▼
                         mDecoders      mEntries (ArrayList)
                              │              │
                              ▼              ▼
                    IResourceDecoder  DictionaryEntry[]
                         .Decode           (Key, Value)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ResourceReader.cls | `Source/CorLib/System.Resources/ResourceReader.cls` | ソース | メインクラス |
| IResourceReader.cls | `Source/CorLib/System.Resources/IResourceReader.cls` | ソース | インターフェース |
| IResourceDecoder.cls | `Source/CorLib/System.Resources/IResourceDecoder.cls` | ソース | デコーダーインターフェース |
| StringResourceDecoder.cls | `Source/CorLib/System.Resources/StringResourceDecoder.cls` | ソース | 文字列デコーダー |
| BitMapResourceDecoder.cls | `Source/CorLib/System.Resources/BitMapResourceDecoder.cls` | ソース | ビットマップデコーダー |
| IconResourceDecoder.cls | `Source/CorLib/System.Resources/IconResourceDecoder.cls` | ソース | アイコンデコーダー |
| CursorResourceDecoder.cls | `Source/CorLib/System.Resources/CursorResourceDecoder.cls` | ソース | カーソルデコーダー |
| ResourceEnumerator.cls | `Source/CorLib/System.Resources/ResourceEnumerator.cls` | ソース | 列挙子 |
