# 機能設計書 34-文字列変換・エンコーディング

## 概要

本ドキュメントは、Julia Base ライブラリにおける文字列変換・エンコーディング機能の設計を記述する。`parse` / `string` / `repr` / `transcode` / `escape_string` / `unescape_string` などの変換関数を提供する。

### 本機能の処理概要

本機能は、文字列と他のデータ型（整数、浮動小数点数、複素数、ブーリアン等）との相互変換、およびエスケープ処理・エンコーディング変換を提供する。

**業務上の目的・背景**：データの入出力において、テキスト形式と内部表現の間の変換は基本的かつ必須の操作である。設定ファイルからの数値読み取り、ユーザー入力のパース、デバッグ出力のための文字列化、エスケープシーケンスの処理など、あらゆるプログラムで使用される。

**機能の利用シーン**：ユーザー入力の数値変換、数値の進数変換表示、文字列の安全なエスケープ処理、UTF-8/UTF-16/UTF-32 間のトランスコーディング、データのシリアライズ/デシリアライズ。

**主要な処理内容**：
1. `parse(T, str; base)` による文字列から数値型への変換
2. `tryparse(T, str)` による安全な（例外なし）パース
3. `string(x...)` によるオブジェクトの文字列化
4. `repr(x)` による Julia 構文表現の文字列化
5. `escape_string` / `unescape_string` によるエスケープ処理
6. `transcode` による文字エンコーディング変換
7. 整数パースにおける進数指定（2-62進数対応）
8. 浮動小数点パースにおける C ランタイム関数の利用
9. 複素数パースにおける実部・虚部の分離

**関連システム・外部連携**：C ランタイムライブラリ（`jl_try_substrtod` / `jl_try_substrtof` 経由の浮動小数点パース）。

**権限による制御**：該当なし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | REPL | 主画面 | 文字列と数値の相互変換 |

## 機能種別

データ変換 / エンコーディング処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| T | Type | Yes | パース先の型（Integer, Float, Complex, Bool） | サポートされた型であること |
| str/s | AbstractString | Yes | 変換対象の文字列 | 空文字列チェックあり |
| base | Integer | No | 整数パースの基数（2-62） | 2 <= base <= 62 |
| c | AbstractChar | No | parse(T, c; base) の文字入力 | 有効な数字文字 |

### 入力データソース

関数の引数として直接受け取る。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| parse結果 | T | 指定型への変換結果 |
| tryparse結果 | Union{T, Nothing} | 変換結果または nothing |
| string結果 | String | 文字列表現 |
| repr結果 | String | Julia 構文表現 |
| escape_string結果 | String | エスケープ済み文字列 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. parse(::Type{T<:Integer}, s; base)
   └─ parseint_preamble: 空白スキップ、符号判定、base=0時の自動検出（0b/0o/0x）
   └─ tryparse_internal: 各桁を __convert_digit で変換、n = n*base + d
   └─ オーバーフロー検出: mul_with_overflow / add_with_overflow
2. parse(::Type{T<:Real}, s)
   └─ tryparse_internal -> tryparse(T, s)
   └─ Float64: ccall(:jl_try_substrtod, ...) で C ランタイム経由
   └─ Float32: ccall(:jl_try_substrtof, ...) で C ランタイム経由
3. parse(::Type{Complex{T}}, s)
   └─ tryparse_internal(Complex{T}, s, i, e, raise)
   └─ 実部と虚部の分離（±区切り、im/i/j 接尾辞）
   └─ 各部を tryparse_internal(T, ...) でパース
4. parse(::Type{Bool}, s)
   └─ "true"/"false" の文字列比較
   └─ 数値表現（0/1）のフォールバック
```

### フローチャート

```mermaid
flowchart TD
    A[開始: parse T, str] --> B{T の型判定}
    B -->|Integer| C[parseint_preamble]
    C --> D[空白スキップ・符号判定]
    D --> E{base=0?}
    E -->|Yes| F[0b/0o/0x で自動検出]
    E -->|No| G[指定 base を使用]
    F --> H[tryparse_internal: 桁変換ループ]
    G --> H
    H --> I{オーバーフロー?}
    I -->|Yes| J[throw OverflowError]
    I -->|No| K[return 変換結果]
    B -->|Float64/Float32| L[ccall jl_try_substrtod/f]
    L --> M{成功?}
    M -->|Yes| N[return 浮動小数点値]
    M -->|No| O[throw ArgumentError]
    B -->|Complex| P[実部・虚部分離]
    P --> Q[各部を再帰的にパース]
    Q --> R[return Complex T, re, im]
    B -->|Bool| S[true/false 文字列比較]
    S --> T[return Bool値]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-34-01 | 自動進数検出 | base=0（またはnothing）で 0b=2進、0o=8進、0x=16進を自動検出 | parse(Integer, ...; base=nothing) |
| BR-34-02 | 進数範囲 | 2 <= base <= 62 | parse(Integer, ...; base) |
| BR-34-03 | 大小文字の数字 | base<=36: a-z は 10-35、base>36: A-Z は 10-35, a-z は 36-61 | __convert_digit |
| BR-34-04 | 前後空白許容 | parse は入力文字列の前後の空白を無視する | parse(Integer, ...) |
| BR-34-05 | 複素数フォーマット | R+Iim / R-Iim / Ri / Rj 形式をサポート | parse(Complex, ...) |
| BR-34-06 | Bool パース | "true"/"false" 文字列および 0/1 数値をサポート | parse(Bool, ...) |

### 計算ロジック

- 整数パース: `n = n * base + d`（各桁）、`mul_with_overflow` / `add_with_overflow` でオーバーフロー検出
- 桁変換: `__convert_digit` で文字を数値に変換（'0'-'9' -> 0-9, 'A'-'Z' -> 10-35, 'a'-'z' -> 10-35 or 36-61）
- 高速オーバーフロー判定: `m = div(typemax(T) - base + 1, base)` で事前閾値を算出

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

該当なし。

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentError | 空文字列または空白のみの入力 | 有効な文字列を指定 |
| - | ArgumentError | 無効な base 値（2-62の範囲外） | 有効な base を指定 |
| - | ArgumentError | 指定 base に対して無効な数字文字 | 有効な数字文字を使用 |
| - | OverflowError | 整数パースでオーバーフロー | より大きな型（BigInt等）を使用 |
| - | ArgumentError | 浮動小数点パースの失敗 | 有効な浮動小数点表現を使用 |
| - | ArgumentError | Bool パースで true/false/0/1 以外 | 有効な Bool 表現を使用 |

### リトライ仕様

該当なし。`tryparse` を使用することで例外なしのパースが可能。

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

該当なし。

## パフォーマンス要件

- 整数パースでは base=10 と base=16 の場合に特別な除算最適化を適用
- `reinterpret(UInt32, c) >> 24` によるASCII高速パスで桁変換を最適化
- 浮動小数点パースは C ランタイム関数への ccall により高速化
- `String`/`SubString{String}` に対する Bool パースでは `memcmp` による高速文字列比較

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

該当なし。数値変換のみであり、特別なセキュリティ考慮事項はない。

## 備考

- `tryparse` は `parse` の例外なしバージョンであり、失敗時に `nothing` を返す
- `parse(Int, "0xff")` のように base 省略で 16 進数を自動認識可能
- Float16 のパースは Float32 経由で変換される
- 複素数パースでは指数符号（e/E の後の +/-）を実部/虚部の区切りと誤認しないよう処理

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parse.jl | `base/parse.jl` | parse(type, str; base) の公開インターフェース（7-38行目） |

**読解のコツ**: parse.jl は型ごとにメソッドが分かれており、`tryparse_internal` が共通の内部関数として各型のパースを実装している。

#### Step 2: 整数パースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | parse.jl | `base/parse.jl` | parseint_preamble（58-91行目）: 空白スキップ・符号・進数検出 |
| 2-2 | parse.jl | `base/parse.jl` | __convert_digit（97-109行目）: 文字→数値変換 |
| 2-3 | parse.jl | `base/parse.jl` | tryparse_internal(Integer)（112-183行目）: 整数パース本体 |

**主要処理フロー**:
1. **58-91行目**: `parseint_preamble` で空白除去、符号判定、0b/0o/0x による進数自動検出
2. **134-136行目**: `m = div(typemax(T) - base + 1, base)` でオーバーフロー閾値を事前計算
3. **138-154行目**: `n <= m` の間は高速ループ、超過後は `mul_with_overflow`/`add_with_overflow` で安全計算
4. **140行目**: `reinterpret(UInt32, c) >> 24` でASCII文字の高速変換

#### Step 3: 浮動小数点パースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | parse.jl | `base/parse.jl` | tryparse(Float64, s::String)（262-266行目）: ccall による C ランタイム利用 |
| 3-2 | parse.jl | `base/parse.jl` | tryparse(Float32, s::String)（282-286行目）: 同上 |

#### Step 4: 複素数・Boolパースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | parse.jl | `base/parse.jl` | tryparse_internal(Complex)（310-365行目）: 実部/虚部の分離ロジック |
| 4-2 | parse.jl | `base/parse.jl` | tryparse_internal(Bool)（185-233行目）: true/false/0/1 パース |

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

```
parse(T::Type{<:Integer}, s; base)
    |
    +-- check_valid_base(base)
    +-- tryparse_internal(T, s, first, last, base, true)
            |
            +-- parseint_preamble(signed, base, s, start, end)
            |       +-- parseint_iterate(s, pos, end)
            |       +-- 空白スキップ / 符号判定 / 0b,0o,0x 検出
            |
            +-- __convert_digit(c, base) [各桁変換]
            +-- mul_with_overflow / add_with_overflow [オーバーフロー検出]

parse(T::Type{<:Real}, s)
    |
    +-- tryparse_internal(T, s, true)
            +-- tryparse(T, s)
                    +-- ccall(:jl_try_substrtod, ...) [Float64]
                    +-- ccall(:jl_try_substrtof, ...) [Float32]

parse(T::Type{Complex{S}}, s)
    |
    +-- tryparse_internal(Complex{S}, s, first, last, true)
            +-- findnext(in(('+','-')), s, i) [±区切り検索]
            +-- findprev(in(('m','i','j')), s, e) [im/i/j接尾辞検索]
            +-- tryparse_internal(S, s, start, end, raise) [実部/虚部]

tryparse(T, s)
    |
    +-- tryparse_internal(T, s, ..., false)  [raise=false]
```

### データフロー図

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

str: "1234" -----------> parse(Int, str) -----------> Int: 1234
  + base: 10                  |
                              +-> parseint_preamble
                              +-> __convert_digit (各桁)
                              +-> n = n*10 + d

str: "1.2e-3" ---------> parse(Float64, str) -------> Float64: 0.0012
                              |
                              +-> ccall(:jl_try_substrtod)

str: "3.2+4.5im" ------> parse(Complex{Float64}, str) -> Complex: 3.2+4.5im
                              |
                              +-> ±位置検出 -> 実部/虚部分離
                              +-> 各部を parse(Float64, ...)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| parse.jl | `base/parse.jl` | ソース | parse/tryparse の主要実装（整数・浮動小数点・複素数・Bool） |
| strings/io.jl | `base/strings/io.jl` | ソース | string 関数の定義 |
| show.jl | `base/show.jl` | ソース | repr 関数の定義 |
| strings/escape.jl | `base/strings/escape.jl` | ソース | escape_string / unescape_string の実装 |
| strings/unicode.jl | `base/strings/unicode.jl` | ソース | transcode 関数の実装 |
| checked.jl | `base/checked.jl` | ソース | add_with_overflow / mul_with_overflow |
