# 機能設計書 108-Base64

## 概要

本ドキュメントは、Julia標準ライブラリ `Base64` モジュールが提供するBase64エンコード・デコード機能の設計を記述する。バイナリデータをASCIIテキストに変換するBase64方式のエンコード/デコードを、パイプ型ストリームおよび関数型インターフェースの両方で提供する。

### 本機能の処理概要

**業務上の目的・背景**：バイナリデータをテキストとして安全に転送・保存する必要がある場面（HTTP通信、電子メール、データURI、JSON内のバイナリデータ埋め込み等）で使用される標準的なエンコーディング方式を提供する。JuliaのMIME表示システム（`stringmime`）でもバイナリMIMEタイプの文字列化に使用される。

**機能の利用シーン**：HTTPレスポンスのバイナリデータエンコード、MIMEデータの文字列表現、ファイルのテキスト埋め込み、認証トークンのエンコード/デコード。

**主要な処理内容**：
1. `Base64EncodePipe` -- 書き込み専用パイプ型エンコーダー
2. `Base64DecodePipe` -- 読み込み専用パイプ型デコーダー
3. `base64encode` -- 関数型エンコードインターフェース
4. `base64decode` -- 関数型デコードインターフェース
5. `stringmime` -- MIMEデータのBase64エンコード付き文字列化
6. `Buffer` -- 内部バッファ管理

**関連システム・外部連携**：Base.Multimedia（MIME/show/display システム）。

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

## 関連画面

本機能に直接関連する画面はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | MIME表示やデータ転送のバックエンド処理として利用 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ostream | IO | Yes（EncodePipe時） | エンコード出力先ストリーム | 書き込み可能 |
| istream | IO | Yes（DecodePipe時） | デコード入力元ストリーム | 読み込み可能 |
| s | String | Yes（base64decode時） | Base64エンコード済み文字列 | 有効なBase64文字列 |
| writefunc | Function | No | base64encodeのカスタム書き込み関数 | IO引数を取る関数 |
| context | IO / Pair | No | IOContextの属性 | - |

### 入力データソース

バイナリデータ（エンコード時）、Base64テキスト（デコード時）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| encoded_string | String | Base64エンコード済みASCII文字列 |
| decoded_bytes | Vector{UInt8} | デコードされたバイナリデータ |

### 出力先

- `Base64EncodePipe`: 内部IOストリーム
- `base64encode`: 戻り値としてString
- `Base64DecodePipe`: read/unsafe_readで読み出し
- `base64decode`: 戻り値としてVector{UInt8}

## 処理フロー

### 処理シーケンス

```
1. エンコード処理
   ├─ 3バイトずつ読み込み（トリプレット）
   ├─ 6ビットずつ4文字のBase64文字に変換
   ├─ 端数は '=' でパディング
   └─ close()で残りバイトを出力
2. デコード処理
   ├─ 4文字ずつ読み込み
   ├─ BASE64_DECODEテーブルで逆変換
   ├─ 3バイトに復元
   └─ パディング/末尾処理
```

### フローチャート

```mermaid
flowchart TD
    subgraph エンコード
    A["write(pipe, data)"] --> B["loadtriplet!(): 3バイト読み込み"]
    B --> C["encode(): 6bit -> Base64文字"]
    C --> D["write(pipe.io, encoded)"]
    D --> E{"残りバイト?"}
    E -->|あり| B
    E -->|なし| F["close(): パディング出力"]
    end
    subgraph デコード
    G["read(pipe, UInt8)"] --> H["read_until_end()"]
    H --> I["decode(): Base64文字 -> 6bit"]
    I --> J{"4文字揃った?"}
    J -->|はい| K["3バイト復元"]
    J -->|いいえ| L["decode_slow(): 端数処理"]
    K --> M["バッファに格納"]
    L --> M
    end
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-108-1 | RFC 4648準拠 | 標準Base64アルファベット（A-Z, a-z, 0-9, +, /）と '=' パディング | 全エンコード/デコード |
| BR-108-2 | パイプ完了要件 | Base64EncodePipeは必ずclose()で完了（パディング出力） | エンコード完了時 |
| BR-108-3 | 不正データ検出 | 不正なBase64文字列はArgumentError("malformed base64 sequence")を送出 | デコード時 |
| BR-108-4 | stringmime統合 | バイナリMIMEタイプはBase64エンコードして文字列化 | stringmime呼び出し時 |

### 計算ロジック

- エンコード: 3バイト入力 -> 4文字出力（3x8bit = 24bit -> 4x6bit）
  - `b1 >> 2`, `b1 << 4 | b2 >> 4`, `b2 << 2 | b3 >> 6`, `b3 & 0x3f`
- デコード: 4文字入力 -> 3バイト出力
  - `b1 << 2 | b2 >> 4`, `b2 << 4 | b3 >> 2`, `b3 << 6 | b4`
- パディング: 入力が3の倍数でない場合、末尾に '=' を追加（1バイト余り=2個、2バイト余り=1個）

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentError | 不正なBase64シーケンス | 入力データの形式を確認 |
| - | EOFError | デコードデータの途中でストリーム終端 | 完全なBase64データを提供 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- 内部バッファサイズ512バイトでバッファリング
- エンコード/デコードともに高速パス（4文字/3バイト単位の一括処理）とスローパス（端数処理）を分離
- `@inbounds` によるバウンドチェック回避

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

- Base64は暗号化ではなくエンコーディングであり、機密データの保護には使用できない
- タイミング攻撃に対する耐性は考慮されていない

## 備考

- `base64encode` は `sprint` のBase64版として設計されている
- `context` キーワード引数でIOContext属性を渡すことが可能
- `finalizer` でBase64EncodePipeの自動close（GC時）を保証

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | buffer.jl | `stdlib/Base64/src/buffer.jl` | `Buffer` 構造体（4-13行目）: data(Memory{UInt8}), offset, sizeフィールド。consumed!/read_to_bufferでバッファ管理 |
| 1-2 | encode.jl | `stdlib/Base64/src/encode.jl` | `BASE64_ENCODE` テーブル（4行目）: 64文字のエンコードテーブル。A-Z, a-z, 0-9, +, / |
| 1-3 | decode.jl | `stdlib/Base64/src/decode.jl` | `BASE64_DECODE` テーブル（4-11行目）: 256要素の逆引きテーブル。BASE64_CODE_END/PAD/IGNの特殊値 |

**読解のコツ**: BufferはMemory{UInt8}をバックエンドとする簡易リングバッファ。offsetとsizeで有効データ範囲を管理し、consumed!で消費、read_to_bufferで補充する。

#### Step 2: エンコード処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | encode.jl | `stdlib/Base64/src/encode.jl` | `Base64EncodePipe{T}` 構造体（34-45行目）: IO + Bufferで構成 |
| 2-2 | encode.jl | `stdlib/Base64/src/encode.jl` | `unsafe_write(pipe, ptr, n)`（52-101行目）: 3バイト単位のエンコードループ |
| 2-3 | encode.jl | `stdlib/Base64/src/encode.jl` | `close(pipe)`（112-137行目）: 端数処理とパディング出力 |
| 2-4 | encode.jl | `stdlib/Base64/src/encode.jl` | `loadtriplet!(buffer, ptr, n)`（140-188行目）: バッファとポインタから3バイト読み込み |
| 2-5 | encode.jl | `stdlib/Base64/src/encode.jl` | `base64encode(f, args...)`（207-218行目）: 関数型エンコードAPI |

**主要処理フロー**:
1. **52-56行目**: loadtriplet!でバッファ残とポインタから3バイトを合成
2. **73-77行目**: 3バイト -> 4バイトのBase64変換（ビットシフト演算）
3. **86-89行目**: バッファが満杯になったらIOに書き出し
4. **112-137行目**: close時に残り1-2バイトのパディング処理

#### Step 3: デコード処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | decode.jl | `stdlib/Base64/src/decode.jl` | `Base64DecodePipe{T}` 構造体（35-44行目）: IO + Buffer + rest(Vector{UInt8}) |
| 3-2 | decode.jl | `stdlib/Base64/src/decode.jl` | `read_until_end(pipe, ptr, n)`（60-104行目）: 高速パスとスローパスの分岐 |
| 3-3 | decode.jl | `stdlib/Base64/src/decode.jl` | `decode_slow(b1,b2,b3,b4,...)`（135-182行目）: 端数・パディング・無効文字の処理 |
| 3-4 | decode.jl | `stdlib/Base64/src/decode.jl` | `base64decode(s)`（217-224行目）: 関数型デコードAPI |

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

```
base64encode(f, args...) / Base64EncodePipe(io)
    │
    ├─ Buffer(512)                    -- 内部バッファ生成
    │
    ├─ write(pipe, data) -> unsafe_write(pipe, ptr, n)
    │      ├─ loadtriplet!(buffer, ptr, n)  -- 3バイト読み込み
    │      └─ encode(b >> 2) x 4            -- Base64変換
    │
    └─ close(pipe)
           └─ パディング処理（1-2バイト端数）

base64decode(s) / Base64DecodePipe(io)
    │
    ├─ Buffer(512)                    -- 内部バッファ生成
    │
    └─ read(pipe) -> read_until_end(pipe, ptr, n)
           ├─ decode(buffer[i]) x 4        -- 逆Base64変換（高速パス）
           └─ decode_slow(...)              -- 端数・パディング処理（スローパス）
```

### データフロー図

```
[エンコード]
バイナリデータ ──▶ loadtriplet!() ──▶ 3バイト ──▶ encode() x 4 ──▶ Base64文字列
                                                                        │
                                                                   close() ──▶ パディング追加

[デコード]
Base64文字列 ──▶ decode() x 4 ──▶ 3バイト ──▶ Vector{UInt8}
                     │
              decode_slow() ──▶ 端数処理
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Base64.jl | `stdlib/Base64/src/Base64.jl` | ソース | メインモジュール・stringmime定義 |
| buffer.jl | `stdlib/Base64/src/buffer.jl` | ソース | 内部Bufferデータ構造 |
| encode.jl | `stdlib/Base64/src/encode.jl` | ソース | エンコード処理 |
| decode.jl | `stdlib/Base64/src/decode.jl` | ソース | デコード処理 |
