# 機能設計書 117-ファイルシステムユーティリティ

## 概要

本ドキュメントは、K-Shoot MANIAにおけるファイルシステムユーティリティ機能の設計を記述する。fileExists/dirExists/safeChdir(特殊文字対応)のファイルシステムヘルパー機能を提供する。

### 本機能の処理概要

ファイルやディレクトリの存在確認、安全なディレクトリ移動を行うユーティリティモジュールである。HSPの標準命令を安全にラップし、エラーハンドリングを追加する。

**業務上の目的・背景**：HSPの標準chdir命令は特殊文字を含むパスでエラー12(Runtime Error)を発生させることがある。このユーティリティは事前にディレクトリの存在を確認し、適切なエラーメッセージを表示することで、ユーザーフレンドリーなエラーハンドリングを実現する。

**機能の利用シーン**：楽曲ファイルのディレクトリへの移動、譜面ファイルの存在確認、スコアファイルの保存先ディレクトリ確認など、ファイルシステムへのアクセスが必要なすべての場面で利用される。

**主要な処理内容**：
1. fileExists(p1): ファイルの存在確認をboolで返す
2. dirExists(p1): ディレクトリの存在確認をboolで返す
3. safeChdir(p1): 存在確認付きディレクトリ移動(命令形)
4. safeChdirC(p1, p2): 存在確認付きディレクトリ移動(関数形、結果をboolで返す)
5. FS_UTILS_REPLACE_CHDIR_WITH_SAFE_CHDIRマクロによるchdirの自動置換

**関連システム・外部連携**：HSPの標準ファイルシステム命令(exist, dirlist, chdir)をラップする。

**権限による制御**：権限による制御はない。OSのファイルシステム権限に従う。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 曲選択画面 | 補助機能 | ファイル存在確認・ディレクトリ移動 |
| 4 | プレイ前処理画面 | 補助機能 | 譜面ファイルの有効性検証 |

## 機能種別

ユーティリティ / ファイルシステム操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| p1 | str | Yes | ファイルパスまたはディレクトリパス | - |
| p2 | int | No | safeChdirCの警告ダイアログ表示フラグ(デフォルト: 1) | 0 or 1 |

### 入力データソース

- アプリケーション内部のパス文字列

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| fileExists戻り値 | int(bool) | ファイルが存在する場合1、しない場合0 |
| dirExists戻り値 | int(bool) | ディレクトリが存在する場合1、しない場合0 |
| safeChdirC戻り値 | int(bool) | ディレクトリ移動成功時1、失敗時0 |

### 出力先

- 関数の戻り値
- ダイアログ(safeChdir/safeChdirCでディレクトリ不在時)
- HSPのカレントディレクトリ(chdir実行時)

## 処理フロー

### 処理シーケンス

```
■ fileExists(p1):
1. exist p1 でファイルサイズを取得
   └─ strsizeにファイルサイズが設定される(-1は不在)
2. strsize != -1 の結果をboolで返す

■ dirExists(p1):
1. パス末尾の'/'と'\'を除去
   └─ strtrim(path, 2, '/')、strtrim(path, 2, '\\')
2. 相対パスのみの場合(".", ".."等)は存在として扱う
   └─ return 1
3. dirlist fileListStr, path, 5 でディレクトリ検索
   └─ 5はディレクトリのみ検索フラグ
4. fileListStr != "" の結果をboolで返す

■ safeChdir(p1):
1. dirExists(p1)でディレクトリ存在確認
   └─ 存在しない場合はエラーダイアログを表示
2. chdir p1 でディレクトリ移動

■ safeChdirC(p1, p2):
1. dirExists(p1)でディレクトリ存在確認
2. 存在する場合: chdir p1 → return 1
3. 存在しない場合: p2=1なら警告ダイアログ → return 0
```

### フローチャート

```mermaid
flowchart TD
    A[safeChdir呼び出し] --> B[dirExists確認]
    B --> C{ディレクトリ存在?}
    C -->|Yes| D[chdir実行]
    C -->|No| E[エラーダイアログ表示]
    E --> D
    D --> F[処理終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-117-01 | 特殊文字対応 | パスに特殊文字が含まれる場合、事前チェックでエラーダイアログを表示 | safeChdir/safeChdirC |
| BR-117-02 | 相対パス省略 | ".", "..", "../..", "\\..\\.."の場合は存在確認を省略して存在とみなす | dirExists |
| BR-117-03 | パス正規化 | 末尾の'/'および'\\'を除去してから存在確認する | dirExists |
| BR-117-04 | マクロ置換 | FS_UTILS_REPLACE_CHDIR_WITH_SAFE_CHDIRマクロ定義時、標準chdirがsafeChdirに置換される | コンパイル時 |
| BR-117-05 | 副作用注意 | fileExistsはstrsizeを上書きする(HSPのexist命令の仕様) | fileExists呼び出し後 |

### 計算ロジック

特になし。

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

### 操作別データベース影響一覧

データベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ディレクトリ不在 | dirExists(p1)=0 | 日英バイリンガルのエラーダイアログを表示 |
| Error 12 | HSPランタイムエラー | chdirが失敗した場合 | safeChdirによる事前チェックで回避 |

### リトライ仕様

リトライ処理はない。safeChdir命令はエラー後もchdir p1を実行する。

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

トランザクション管理はない。

## パフォーマンス要件

- ファイル/ディレクトリ存在確認は低コスト操作
- dirlistはファイルシステムへのアクセスを伴うが、単一パスの確認のため高速

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

- パストラバーサルに対する防御は行っていない(アプリケーション内部使用のため)

## 備考

- `#module filesystem_utils`でモジュール化されている
- safeChdirCはマクロ定義によりデフォルト引数p2=1が設定される
- 日本語・英語のバイリンガルエラーメッセージが表示される

---

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

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

### 推奨読解順序

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

ファイルシステムユーティリティはステートレスな関数群であり、永続データ構造はない。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | filesystem_utils.as | `src/filesystem_utils.as` | **1行目**: `#module filesystem_utils` - モジュール宣言 |

**読解のコツ**: HSPの`#defcfunc`は戻り値を持つ関数定義、`#deffunc`は命令(サブルーチン)定義。`val`パラメータは参照渡し。

#### Step 2: fileExists関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | filesystem_utils.as | `src/filesystem_utils.as` | **9-11行目**: fileExists関数定義 |

**主要処理フロー**:
1. **10行目**: `exist p1` - HSP標準命令でファイルサイズを取得
2. **11行目**: `return strsize != -1` - ファイルが存在する場合true

#### Step 3: dirExists関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | filesystem_utils.as | `src/filesystem_utils.as` | **19-34行目**: dirExists関数定義 |

**主要処理フロー**:
1. **23-24行目**: パス末尾の'/'と'\\'を除去
2. **27-29行目**: 相対パスのみ(".", ".."等)の場合は1を返す
3. **32行目**: `dirlist fileListStr, path, 5` - ディレクトリ検索(5はディレクトリのみ)
4. **34行目**: `return fileListStr != ""` - 結果が空でなければ存在

#### Step 4: safeChdir/safeChdirC関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | filesystem_utils.as | `src/filesystem_utils.as` | **42-47行目**: safeChdir命令定義 |
| 4-2 | filesystem_utils.as | `src/filesystem_utils.as` | **55-64行目**: safeChdirC_関数定義(ローカル関数) |
| 4-3 | filesystem_utils.as | `src/filesystem_utils.as` | **67行目**: safeChdirCマクロ定義(デフォルト引数付き) |

**主要処理フロー**:
- **43-44行目**: dirExists確認→失敗時にダイアログ表示
- **46行目**: `chdir p1` - ディレクトリ移動(エラー後も実行)
- **56-63行目**: safeChdirC_: 成功時chdir+return 1、失敗時ダイアログ+return 0

#### Step 5: マクロ置換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | filesystem_utils.as | `src/filesystem_utils.as` | **72-74行目**: chdir→safeChdirマクロ置換 |

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

```
呼び出し元(kshootmania.hsp, select.hsp等)
    |
    +-- fileExists(path)
    |       +-- exist (HSP標準命令)
    |       +-- return strsize != -1
    |
    +-- dirExists(path)
    |       +-- strtrim (パス正規化)
    |       +-- dirlist (ディレクトリ検索)
    |       +-- return fileListStr != ""
    |
    +-- safeChdir(path)
    |       +-- dirExists(path)
    |       +-- dialog (エラー時)
    |       +-- chdir (HSP標準命令)
    |
    +-- safeChdirC(path, showDialog)
            +-- dirExists(path)
            +-- chdir (成功時)
            +-- dialog (失敗かつshowDialog=1時)
            +-- return 0/1
```

### データフロー図

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

パス文字列 ----+--> exist/dirlist ------------> bool結果(存在/不在)
               +--> strtrim (正規化)
               +--> chdir (移動) ------------> カレントディレクトリ変更
               +--> dialog (エラー時) -------> エラーダイアログ表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| filesystem_utils.as | `src/filesystem_utils.as` | ソース | ファイルシステムユーティリティモジュール本体(全75行) |
| kshootmania.hsp | `kshootmania.hsp` | ソース | ゲーム本体。fileExists/safeChdirの主要利用元 |
| kshooteditor.hsp | `kshooteditor.hsp` | ソース | エディタ。ファイル操作時にfileExistsを使用 |
| src/scene/select.hsp | `src/scene/select.hsp` | ソース | 選曲画面。safeChdirでディレクトリ移動 |
