# 機能設計書 40-IniFile

## 概要

本ドキュメントは、VBCorLibライブラリにおけるIniFileクラスの機能設計について記述する。IniFileクラスは、Windows INI形式の設定ファイルの読み書きを行うためのクラスである。

### 本機能の処理概要

**業務上の目的・背景**：アプリケーション設定の保存・読み込みにおいて、INI形式は長年使用されてきた標準的なフォーマットである。IniFileクラスは、INIファイルの読み書きを簡潔なAPIで提供し、セクション・キー・値の管理、型変換付きの値取得、セクション単位のバッチ操作などを可能にする。

**機能の利用シーン**：アプリケーション設定の保存・読み込み、ユーザー設定の永続化、レガシーシステムとのINIファイル連携、設定ファイルのマイグレーションなど、INI形式のファイル操作が必要な場面で利用される。

**主要な処理内容**：
1. 値の書き込み（SetValue）
2. 値の読み込み（GetString、GetInt32、GetInt16、GetByte、GetBoolean、GetDate、GetDouble、GetSingle、GetCurrency、GetDecimal、GetDateTime、GetTimeSpan）
3. セクション名一覧取得（GetSectionNames）
4. キー名一覧取得（GetKeyNames）
5. キー・値ペア一覧取得（GetValues）
6. キー・セクション削除（DeleteKey、DeleteSection）
7. セクションライター取得（GetSectionWriter）
8. バッファフラッシュ（Flush）
9. 自動フラッシュ制御（AutoFlush）

**関連システム・外部連携**：Windows Private Profile API（GetPrivateProfileStringW、WritePrivateProfileStringW等）を直接呼び出し。

**権限による制御**：INIファイルへの書き込み権限に依存。

## 関連画面

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

## 機能種別

設定ファイル操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| FileName | String | Yes | INIファイルのパス | 空文字列の場合はArgumentException |
| Section | String | Yes | セクション名（[section]形式の部分） | 空文字列の場合はArgumentException |
| Key | String | Yes | キー名 | 空文字列の場合はArgumentException |
| Value | Variant | Yes | 書き込む値 | IObject実装オブジェクトまたは基本型 |
| Default | Variant | No | デフォルト値（値が存在しないか変換失敗時に返す） | - |

### 入力データソース

プログラムから直接渡される値およびINIファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| String | String | GetStringで返される値 |
| Long | Long | GetInt32で返される値 |
| Integer | Integer | GetInt16で返される値 |
| Byte | Byte | GetByteで返される値 |
| Boolean | Boolean | GetBooleanで返される値 |
| Date | Date | GetDateで返される値 |
| Double | Double | GetDoubleで返される値 |
| Single | Single | GetSingleで返される値 |
| Currency | Currency | GetCurrencyで返される値 |
| Variant(Decimal) | Variant | GetDecimalで返される値 |
| CorDateTime | CorDateTime | GetDateTimeで返される値 |
| TimeSpan | TimeSpan | GetTimeSpanで返される値 |
| String() | String() | GetSectionNames、GetKeyNamesで返される配列 |
| IDictionary | IDictionary | GetValuesで返されるハッシュテーブル |
| IniResourceWriter | IniResourceWriter | GetSectionWriterで返されるライター |

### 出力先

呼び出し元のプログラムに戻り値として返される、またはINIファイル

## 処理フロー

### 処理シーケンス

```
1. IniFile生成
   └─ ファイル名を保持
2. 値書き込み（SetValue）
   └─ WritePrivateProfileStringW呼び出し
   └─ AutoFlush=TrueならFlush呼び出し
3. 値読み込み（Get系メソッド）
   └─ GetPrivateProfileStringWで文字列取得
   └─ 型変換を実行（失敗時はデフォルト値）
4. 一覧取得
   └─ GetPrivateProfileStringWで取得
   └─ NUL区切りの結果を配列に変換
```

### フローチャート

```mermaid
flowchart TD
    A[IniFile生成] --> B[ファイル名保持]
    B --> C{操作種別}
    C -->|SetValue| D[WritePrivateProfileStringW]
    C -->|Get系| E[GetPrivateProfileStringW]
    C -->|Delete系| F[WritePrivateProfileStringW with NULL]
    C -->|GetValues| G[GetPrivateProfileSectionW]
    D --> H{AutoFlush?}
    H -->|Yes| I[Flush呼び出し]
    H -->|No| J[完了]
    I --> J
    E --> K[型変換]
    K --> L{成功?}
    L -->|Yes| M[変換値を返す]
    L -->|No| N[デフォルト値を返す]
    F --> J
    G --> O[NUL区切りをパース]
    O --> P[IDictionaryを返す]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ディレクトリなしパス | ファイル名のみの場合はWindowsディレクトリに作成 | SetValue実行時 |
| BR-002 | カレントディレクトリ指定 | ".\"で始めるとカレントディレクトリに作成 | SetValue実行時 |
| BR-003 | 空値は空文字列 | NULLを渡すと削除になるため空文字列に変換 | SetValue実行時 |
| BR-004 | 型変換失敗時 | 変換に失敗した場合はデフォルト値を返す | Get系メソッド |
| BR-005 | AutoFlush | AutoFlush=Trueの場合、書き込み後に自動でFlush | SetValue/Delete実行時 |

### 計算ロジック

**バッファサイズ動的拡張**:
```vb
Size = 512
Do
    Size = Size * 2
    Buf = String$(Size, vbNullChar)
    Size = GetPrivateProfileStringW(Section, Key, Default, Buf, Size, mFileName)
Loop While Size = Len(Buf) - 1
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Argument_EmptyPath | ArgumentException | ファイル名が空文字列 | 有効なファイル名を指定 |
| Argument_EmptyIniSection | ArgumentException | セクション名が空文字列 | 有効なセクション名を指定 |
| Argument_EmptyIniKey | ArgumentException | キー名が空文字列 | 有効なキー名を指定 |
| Win32Error | IOException | Windows API呼び出し失敗 | ファイルのアクセス権限を確認 |

### リトライ仕様

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

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

本機能はトランザクション管理を行わない。Flushを呼び出すまで書き込みがキャッシュされる可能性がある。

## パフォーマンス要件

- AutoFlush=Falseの場合、書き込みがキャッシュされて効率化
- 大量の読み書きがある場合はGetValues/GetSectionWriterの使用を推奨

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

- INIファイルへのアクセス権限に依存
- パスワード等の機密情報は暗号化して保存することを推奨
- Windowsディレクトリへの書き込みは管理者権限が必要な場合がある

## 備考

- Windows Private Profile APIを使用しているため、Windows固有の機能
- INIファイル形式：[セクション名] + 改行 + キー=値
- GetSectionWriterでセクション全体を一括書き込み可能

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: mFileName（INIファイルパス）、mAutoFlush（自動フラッシュフラグ）が主要な状態変数。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | IniFile.cls | `Source/CorLib/System.IO/IniFile.cls` | 497-502行目のInit関数 |

**主要処理フロー**:
1. **498-499行目**: 空文字列チェック
2. **501行目**: ファイル名を保持

#### Step 3: 値操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | IniFile.cls | `Source/CorLib/System.IO/IniFile.cls` | 109-126行目のSetValueメソッド |
| 3-2 | IniFile.cls | `Source/CorLib/System.IO/IniFile.cls` | 135-156行目のGetStringメソッド |
| 3-3 | IniFile.cls | `Source/CorLib/System.IO/IniFile.cls` | 166-173行目のGetInt32メソッド |

**主要処理フロー**:
- **118行目**: Convert.ToStringで値を文字列に変換
- **120-121行目**: WritePrivateProfileStringWで書き込み
- **149-153行目**: バッファ拡張ループ
- **167-168行目**: GetStringで取得してCLngで変換

#### Step 4: 一覧・削除操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | IniFile.cls | `Source/CorLib/System.IO/IniFile.cls` | 364-366行目のGetSectionNamesメソッド |
| 4-2 | IniFile.cls | `Source/CorLib/System.IO/IniFile.cls` | 508-528行目のGetList内部関数 |
| 4-3 | IniFile.cls | `Source/CorLib/System.IO/IniFile.cls` | 385-397行目のDeleteKeyメソッド |
| 4-4 | IniFile.cls | `Source/CorLib/System.IO/IniFile.cls` | 420-456行目のGetValuesメソッド |

**主要処理フロー**:
- **365行目**: GetList(vbNullString)でセクション名一覧取得
- **522行目**: Split(Left$(Buf, Size - 1), vbNullChar)でNUL区切りを配列化
- **391行目**: WritePrivateProfileStringWにvbNullStringを渡して削除

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

```
IniFile
    │
    ├─ Init (コンストラクタ)
    │      └─ 空文字列チェック
    │
    ├─ SetValue
    │      ├─ Convert.ToString
    │      ├─ WritePrivateProfileStringW (Win API)
    │      └─ Flush（AutoFlush時）
    │
    ├─ GetString
    │      ├─ GetPrivateProfileStringW (Win API)
    │      └─ バッファ動的拡張
    │
    ├─ GetInt32 / GetInt16 / GetByte / GetBoolean / ...
    │      ├─ GetString
    │      └─ CLng / CInt / CByte / CBool / ... (型変換)
    │
    ├─ GetDateTime
    │      ├─ GetString
    │      └─ CorDateTime.TryParse
    │
    ├─ GetTimeSpan
    │      ├─ GetString
    │      ├─ TimeSpan.TryParse
    │      └─ TimeSpan.FromDate (フォールバック)
    │
    ├─ GetSectionNames
    │      └─ GetList (内部)
    │             ├─ GetPrivateProfileStringW (Win API)
    │             └─ Split
    │
    ├─ GetKeyNames
    │      └─ GetList (内部)
    │
    ├─ GetValues
    │      ├─ GetPrivateProfileSectionW (Win API)
    │      ├─ Split (NUL区切り→配列)
    │      ├─ Split ("="区切り→キー/値)
    │      └─ Hashtable作成
    │
    ├─ DeleteKey
    │      ├─ WritePrivateProfileStringW (vbNullString)
    │      └─ Flush（AutoFlush時）
    │
    ├─ DeleteSection
    │      ├─ WritePrivateProfileStringW (vbNullString)
    │      └─ Flush（AutoFlush時）
    │
    ├─ GetSectionWriter
    │      └─ NewIniResourceWriter
    │
    └─ Flush
           └─ WritePrivateProfileStringW (空引数)
```

### データフロー図

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

Section/Key/Value ───▶ SetValue
                           │
                           ▼
                     WritePrivateProfileStringW
                           │
                           ▼
                     INIファイル ─────────▶ 永続化


Section/Key ───────▶ Get系メソッド
                           │
                           ▼
                     GetPrivateProfileStringW
                           │
                           ▼
                     型変換 ─────────────▶ 値
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IniFile.cls | `Source/CorLib/System.IO/IniFile.cls` | ソース | IniFileクラス本体 |
| IniResourceWriter.cls | `Source/CorLib/System.IO/IniResourceWriter.cls` | ソース | セクション一括書き込み |
| Convert.cls | `Source/CorLib/System/Convert.cls` | ソース | 値の文字列変換 |
| CorDateTime.cls | `Source/CorLib/System/CorDateTime.cls` | ソース | 日時パース |
| TimeSpan.cls | `Source/CorLib/System/TimeSpan.cls` | ソース | 時間間隔パース |
| Hashtable.cls | `Source/CorLib/System.Collections/Hashtable.cls` | ソース | GetValuesの戻り値 |
