# 機能設計書 58-omz_urldecode

## 概要

本ドキュメントは、Oh My Zshの`omz_urldecode`関数の機能設計を記載する。この関数は、URLエンコードされた文字列をデコードするユーティリティ関数である。

### 本機能の処理概要

`omz_urldecode`関数は、RFC 2396準拠でURLエンコードされた（%エスケープされた）文字列をデコードし、元の文字列に戻す。`+`記号はスペースに、`%XX`形式のエスケープは対応する文字に変換される。

**業務上の目的・背景**：WebアプリケーションやCLIツールにおいて、URLから取得したクエリパラメータや、エンコードされたファイル名を人間が読める形式に変換する必要がある場面は頻繁にある。この関数は、zshシェル環境で手軽にURLデコードを行う手段を提供し、omz_urlencode関数と対をなすユーティリティである。

**機能の利用シーン**：
- URLから取得したクエリパラメータをデコードして表示する場合
- エンコードされたファイル名やパスを元に戻す場合
- curlやwgetで取得したデータに含まれるURLエンコード文字列をデコードする場合
- デバッグ目的でエンコードされた文字列を確認する場合

**主要な処理内容**：
1. 入力文字列から呼び出し元のエンコーディングを取得
2. `+`記号をスペースに変換
3. バックスラッシュを保護
4. `%XX`形式のエスケープを`\xXX`形式に変換
5. printfで実際のデコードを実行
6. 必要に応じて呼び出し元のエンコーディングに再変換

**関連システム・外部連携**：zsh/langinfoモジュール、iconvコマンドに依存。

**権限による制御**：特にロールによる制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLIユーティリティ関数のため関連画面なし |

## 機能種別

文字列変換 / デコード処理 / ユーティリティ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $1 (urlstring) | string | Yes | デコードするURLエンコード文字列 | なし |

### 入力データソース

コマンドライン引数として直接入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 標準出力 | string | デコードされた文字列（改行付き） |
| 戻り値 | integer | 0: 成功、非0: エラー（エンコーディング変換失敗等） |

### 出力先

- 標準出力（デコードされた文字列）
- 標準エラー出力（エラーメッセージ）

## 処理フロー

### 処理シーケンス

```
1. エンコーディング情報取得
   └─ $langinfo[CODESET] で現在のエンコーディングを取得
2. + からスペースへの変換
   └─ ${encoded_url:gs/+/ /} で + を空白に置換
3. バックスラッシュ保護
   └─ ${tmp:gs/\\/\\\\/} でバックスラッシュをエスケープ
4. %エスケープの変換
   └─ ${tmp:gs/%/\\x/} で %XX を \xXX に変換
5. printfによるデコード
   └─ printf -- "$tmp" で実際のデコードを実行
6. エンコーディング再変換（必要な場合）
   └─ UTF-8以外の場合、iconvで変換
7. 結果出力
   └─ echo -E でデコード結果を出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[エンコーディング取得]
    B --> C[+をスペースに変換]
    C --> D[バックスラッシュ保護]
    D --> E[%XXを\xXXに変換]
    E --> F[printfでデコード]
    F --> G{エンコーディングがUTF-8?}
    G -->|Yes| H[結果を出力]
    G -->|No| I[iconvで変換]
    I --> J{変換成功?}
    J -->|Yes| H
    J -->|No| K[エラー出力]
    K --> L[戻り値1を返す]
    H --> M[終了]
    L --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-58-1 | RFC 2396準拠 | URLデコードはRFC 2396に準拠する | 常時 |
| BR-58-2 | +変換 | +記号はスペースに変換される | 常時 |
| BR-58-3 | %エスケープ | %XX形式のエスケープは対応する文字に変換 | 常時 |
| BR-58-4 | UTF-8前提 | デコード後の文字列はUTF-8として扱われる | 常時 |
| BR-58-5 | エンコーディング変換 | 呼び出し元がUTF-8以外の場合、結果を変換する | 非UTF-8環境 |

### 計算ロジック

デコード処理の主要ロジック：
```zsh
# + をスペースに変換
local tmp=${encoded_url:gs/+/ /}

# バックスラッシュを保護（printf で解釈されないように）
tmp=${tmp:gs/\\/\\\\/}

# %XX を \xXX に変換（printf の \x エスケープとして）
tmp=${tmp:gs/%/\\x/}

# printf でデコード
local decoded="$(printf -- "$tmp")"
```

zshの`${var:gs/pattern/replacement/}`構文（グローバル置換）を使用している。

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | エンコーディング変換エラー | iconvによるUTF-8から他エンコーディングへの変換に失敗 | 入力データの確認、エンコーディング設定の確認 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

文字列置換とprintfによる処理のため、文字列長に比例した線形時間（O(n)）。

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

- デコード後の文字列には任意の文字が含まれる可能性がある
- printfを使用するため、入力に含まれるエスケープシーケンスに注意が必要
- バックスラッシュの保護処理により、意図しないエスケープを防止している

## 備考

- omz_urlencode関数とペアで使用される
- 不正なURLエンコード文字列でも処理は試みられる（エラーにならない場合がある）
- UTF-8が前提だが、他のエンコーディング環境でも動作するよう設計されている

---

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

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

### 推奨読解順序

#### Step 1: 関数全体の構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | functions.zsh | `lib/functions.zsh` | omz_urldecode関数の定義（254-284行目） |

**読解のコツ**: この関数は比較的短いため、以下の順序で読むことを推奨：
1. コメント部分（240-253行目）で機能概要を把握
2. 変数初期化部分（255-261行目）
3. 文字列置換処理（264-268行目）
4. printfによるデコード（269行目）
5. エンコーディング再変換（271-281行目）

#### Step 2: ドキュメントコメントを読む

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | functions.zsh | `lib/functions.zsh` | 関数上部のコメント（240-253行目） |

**ドキュメントコメントの内容**:
- RFC 2396準拠のURLデコード
- +と%エスケープの処理説明
- 使用例

#### Step 3: 文字列置換処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | functions.zsh | `lib/functions.zsh` | 文字列置換処理（264-268行目） |

**主要処理フロー**:
- **264行目**: `local tmp=${encoded_url:gs/+/ /}` - +をスペースに変換
- **266行目**: `tmp=${tmp:gs/\\/\\\\/}` - バックスラッシュを保護
- **268行目**: `tmp=${tmp:gs/%/\\x/}` - %XXを\xXXに変換

**zsh文法の解説**:
- `${var:gs/pattern/replacement/}`：グローバル置換（:gsはglobal substitute）

#### Step 4: エンコーディング変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | functions.zsh | `lib/functions.zsh` | エンコーディング変換（273-281行目） |

**主要処理フロー**:
- **273-274行目**: 安全なエンコーディングの定義（UTF-8, utf8, US-ASCII）
- **275-280行目**: 非UTF-8環境でのiconv変換

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

```
omz_urldecode()
    │
    ├─ $langinfo[CODESET] (zsh/langinfo)
    │       └─ 現在のエンコーディング取得
    │
    ├─ ${var:gs/.../} (zsh組み込み)
    │       └─ 文字列置換
    │
    ├─ printf (シェルビルトイン)
    │       └─ \xXX形式のデコード
    │
    ├─ iconv (外部コマンド - 条件付き)
    │       └─ UTF-8から他エンコーディングへ変換
    │
    └─ echo -E (zshビルトイン)
            └─ 結果出力
```

### データフロー図

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

URLエンコード文字列
        │
        ▼
  + → スペース変換
        │
        ▼
  バックスラッシュ保護
        │
        ▼
  %XX → \xXX変換
        │
        ▼
  printf デコード
        │
        ▼
  [UTF-8文字列]
        │
        ├─ [UTF-8環境] ──────────▶ 出力
        │
        └─ [非UTF-8環境]
               │
               ▼
           iconv変換
               │
               ▼
           出力 ─────────────────▶ デコード文字列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| functions.zsh | `lib/functions.zsh` | ソース | omz_urldecode関数およびomz_urlencode関数の定義 |
| oh-my-zsh.sh | `oh-my-zsh.sh` | ソース | lib/functions.zshを読み込むエントリポイント |
