# 機能設計書 22-ハンドル型情報取得

## 概要

本ドキュメントは、libuv の `uv_handle_get_type()` および `uv_handle_type_name()` 関数によるハンドルの型情報取得機能の設計を記述する。

### 本機能の処理概要

本機能は、ハンドルインスタンスの型情報を取得するための2つの関数を提供する。`uv_handle_get_type()`はハンドルの型を列挙値として返し、`uv_handle_type_name()`はハンドル型を人間が読める文字列名に変換する。

**業務上の目的・背景**：libuvではすべてのハンドルが`uv_handle_t`を基底型として共有するため、実行時にハンドルの具体的な型を判定する必要がある。ログ出力やデバッグ時にはハンドル型を文字列として表示する必要があり、これらの関数がその要求を満たす。また、言語バインディングでの型判定にも利用される。

**機能の利用シーン**：
- uv_walk()でイベントループ上の全ハンドルを走査し、各ハンドルの型を判定する場合
- デバッグログでハンドルの型名を出力する場合
- 汎用的なハンドル処理関数でハンドル型に応じた分岐を行う場合

**主要な処理内容**：
1. `uv_handle_get_type()`: ハンドル構造体の`type`フィールドを返却
2. `uv_handle_type_name()`: `UV_HANDLE_TYPE_MAP`マクロを使用してswitch文で型名文字列を返却
3. 特殊ケース（UV_FILE, UV_HANDLE_TYPE_MAX, UV_UNKNOWN_HANDLE）の処理

**関連システム・外部連携**：特になし。ライブラリ内部で完結する純粋な情報取得関数。

**権限による制御**：なし。任意のスレッドから呼び出し可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 7 | ハンドル基底 | 主画面 | uv_handle_get_type()/uv_handle_type_name()による型情報取得のAPI定義 |

## 機能種別

情報取得処理（ハンドルの型情報を列挙値または文字列として返却）

## 入力仕様

### 入力パラメータ

#### uv_handle_get_type()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | const uv_handle_t* | Yes | 型を取得するハンドルへのポインタ | NULLでないこと |

#### uv_handle_type_name()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| type | uv_handle_type | Yes | 文字列名に変換するハンドル型 | uv_handle_type列挙値 |

### 入力データソース

呼び出し元から直接引数として渡される。

## 出力仕様

### 出力データ

#### uv_handle_get_type()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | uv_handle_type | ハンドルの型（列挙値） |

#### uv_handle_type_name()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | const char* | ハンドル型の文字列名（例: "tcp", "udp", "pipe"等）。不正な型の場合はNULL |

### 出力先

関数の戻り値として呼び出し元に返却される。

## 処理フロー

### 処理シーケンス

```
uv_handle_get_type():
1. handle->type を直接返却

uv_handle_type_name():
1. switch(type) で分岐
   ├─ UV_HANDLE_TYPE_MAP(XX) マクロ展開: 各型の文字列名を返却
   ├─ UV_FILE: "file" を返却
   └─ UV_HANDLE_TYPE_MAX / UV_UNKNOWN_HANDLE: NULL を返却
2. default: NULL を返却
```

### フローチャート

```mermaid
flowchart TD
    A[uv_handle_type_name 呼び出し] --> B{type の判定}
    B -->|UV_ASYNC| C1["return 'async'"]
    B -->|UV_TCP| C2["return 'tcp'"]
    B -->|UV_FILE| C3["return 'file'"]
    B -->|UV_UNKNOWN_HANDLE / UV_HANDLE_TYPE_MAX| C4["return NULL"]
    B -->|default| C5["return NULL"]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-22-01 | 型フィールド直接返却 | uv_handle_get_type()はhandle->typeをそのまま返す | 常時 |
| BR-22-02 | マクロによる文字列生成 | UV_HANDLE_TYPE_MAPのXXマクロは#lcで文字列リテラルに変換 | uv_handle_type_name() |
| BR-22-03 | UV_FILE特別処理 | UV_FILEはマクロに含まれないため個別にcase文で"file"を返す | type == UV_FILE |
| BR-22-04 | 不正型のNULL返却 | UV_UNKNOWN_HANDLE, UV_HANDLE_TYPE_MAX, 未定義値にはNULLを返す | 未知の型が渡された場合 |

### 計算ロジック

特別な計算ロジックはない。フィールド参照またはswitch文による文字列マッピング。

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

データベース操作は存在しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NULL | 不正引数 | uv_handle_type_name()に未定義の型が渡された場合 | 呼び出し元でNULLチェックを行う |

### リトライ仕様

リトライは不要。

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

トランザクションは存在しない。

## パフォーマンス要件

O(1)の定数時間。`uv_handle_get_type()`は単純なフィールド参照、`uv_handle_type_name()`はswitch文のみ。

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

特になし。読み取り専用の情報取得関数。

## 備考

- `uv_handle_type_name()`が返す文字列は静的文字列リテラルであり、解放の必要はない。
- UV_FILEはUV_HANDLE_TYPE_MAPマクロに含まれない特殊な型で、個別にcase文で処理される。
- 対になる`uv_req_type_name()`/`uv_req_get_type()`が存在する（No.29参照）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_handle_type列挙型の定義（L198-205）。UV_UNKNOWN_HANDLE=0から始まりUV_HANDLE_TYPE_MAXで終わる |
| 1-2 | uv.h | `include/uv.h` | UV_HANDLE_FIELDSマクロ（L463-476）のtypeフィールド（L468） |

**読解のコツ**: `uv_handle_type`列挙型は`UV_HANDLE_TYPE_MAP(XX)`で自動生成される。UV_FILEはマクロ外で個別に定義されている点に注意。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | 関数宣言（L484-485） |
| 2-2 | uv-data-getter-setters.c | `src/uv-data-getter-setters.c` | uv_handle_get_type()の実装（L36-38）とuv_handle_type_name()の実装（L24-34） |

**主要処理フロー**:
1. **36-38行目**: `uv_handle_get_type()` - handle->typeを返すだけの1行関数
2. **24-34行目**: `uv_handle_type_name()` - UV_HANDLE_TYPE_MAPマクロでswitch文を展開。UV_FILEは"file"を返し、UV_HANDLE_TYPE_MAX/UV_UNKNOWN_HANDLEはNULLを返す

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

```
uv_handle_get_type(handle)
    └─ return handle->type

uv_handle_type_name(type)
    └─ switch(type)
           ├─ UV_HANDLE_TYPE_MAP(XX) → return #lc (文字列化)
           ├─ UV_FILE → return "file"
           └─ UV_UNKNOWN_HANDLE / UV_HANDLE_TYPE_MAX → return NULL
```

### データフロー図

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

uv_handle_t* ───▶ handle->type参照 ───▶ uv_handle_type (列挙値)

uv_handle_type ───▶ switch分岐 ───▶ const char* (型名文字列 or NULL)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | 型定義・関数宣言・UV_HANDLE_TYPE_MAPマクロ |
| uv-data-getter-setters.c | `src/uv-data-getter-setters.c` | ソース | uv_handle_get_type()とuv_handle_type_name()の実装 |
