# 機能設計書 14-string_decoder

## 概要

本ドキュメントは、Node.jsのstring_decoderモジュール（Bufferから文字列へのデコード機能）の機能設計を記述したものである。

### 本機能の処理概要

string_decoder機能は、バイナリデータ（Buffer）を文字列に変換する際に、マルチバイト文字が途中で分割されている場合でも正しく処理するための機能を提供する。ストリーム処理でデータがチャンク単位で到着する際に、文字境界を適切に処理する。

**業務上の目的・背景**：ストリームでテキストデータを受信する際、TCP/IPパケット境界やバッファサイズの制約により、UTF-8などのマルチバイト文字が途中で分割されることがある。string_decoderはこの問題を解決し、文字化けを防ぐ。

**機能の利用シーン**：
- ストリームからのテキストデータ読み取り
- ネットワーク通信でのテキスト受信
- ファイル読み取りでのテキスト処理
- HTTPレスポンスボディの処理
- ログファイルのストリーム処理

**主要な処理内容**：
1. StringDecoder: デコーダーインスタンス生成
2. write(): バッファを文字列に変換（不完全文字は保持）
3. end(): 残りのバッファを文字列に変換（ストリーム終了時）
4. エンコーディング対応: utf8, utf16le, latin1, base64, base64url, hex

**関連システム・外部連携**：
- stream: Readableストリームの内部で使用
- buffer: 入力データ形式
- fs: ファイル読み取りストリーム

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

## 関連画面

本機能はCLI/APIレベルの機能であり、直接関連する画面はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

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

## 入力仕様

### 入力パラメータ

#### StringDecoderコンストラクタ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| encoding | string | No | 文字エンコーディング | utf8/utf16le/latin1/base64/base64url/hex |

#### write()メソッド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| buf | Buffer/TypedArray/DataView/string | Yes | デコード対象データ | ArrayBufferView |

#### end()メソッド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| buf | Buffer/TypedArray/DataView/string | No | 追加のデコード対象データ | ArrayBufferView |

### 入力データソース

- Buffer（ストリームからのチャンク）
- TypedArray/DataView
- 文字列（そのまま返却）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| decodedString | string | デコードされた文字列 |

### 出力先

- アプリケーションコード（戻り値）

## 処理フロー

### 処理シーケンス

```
1. StringDecoder生成
   └─ エンコーディング正規化
   └─ 内部バッファ初期化
2. write()呼び出し
   └─ 前回の不完全文字と結合
   └─ デコード実行
   └─ 不完全文字を内部バッファに保持
   └─ 完全な文字列を返却
3. end()呼び出し（ストリーム終了時）
   └─ 残りのバッファをフラッシュ
   └─ 不完全文字は置換文字として出力
```

### フローチャート

```mermaid
flowchart TD
    A[new StringDecoder] --> B[encoding正規化]
    B --> C[内部バッファ初期化]

    D[write buf] --> E{文字列?}
    E -->|Yes| F[そのまま返却]
    E -->|No| G[decode関数呼び出し]

    G --> H{不完全文字あり?}
    H -->|Yes| I[内部バッファに保持]
    H -->|No| J[デコード結果返却]
    I --> J

    K[end buf] --> L{bufあり?}
    L -->|Yes| M[write buf]
    L -->|No| N[空文字]
    M --> O{内部バッファあり?}
    N --> O
    O -->|Yes| P[flush関数呼び出し]
    O -->|No| Q[結果返却]
    P --> Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 文字列パススルー | write()に文字列が渡された場合はそのまま返却 | string入力時 |
| BR-002 | 不完全文字保持 | マルチバイト文字が途中で切れている場合は次回に繰り越し | write()時 |
| BR-003 | 終了時フラッシュ | end()で残りの不完全文字を出力 | end()呼び出し時 |
| BR-004 | デフォルトUTF-8 | エンコーディング未指定時はUTF-8 | コンストラクタ |

### 計算ロジック

#### 不完全文字検出（UTF-8）
```
UTF-8バイトシーケンス:
- 1バイト文字: 0xxxxxxx
- 2バイト文字: 110xxxxx 10xxxxxx
- 3バイト文字: 1110xxxx 10xxxxxx 10xxxxxx
- 4バイト文字: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

末尾バイトを検査し、必要なバイト数を計算
```

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

本機能はデータベースを直接操作しない。

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR_UNKNOWN_ENCODING | TypeError | 不明なエンコーディング | 有効なエンコーディングを指定 |
| ERR_INVALID_ARG_TYPE | TypeError | 引数の型が不正 | Buffer/TypedArray/DataViewを渡す |
| ERR_INVALID_THIS | TypeError | thisがStringDecoderでない | 正しいインスタンスで呼び出す |

### リトライ仕様

本機能にリトライ仕様はない。

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

本機能にトランザクション仕様はない。

## パフォーマンス要件

- ネイティブ実装（C++）により高速処理
- 内部バッファは最小限（最大4バイト：UTF-8の最大文字長）

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

- 不正なUTF-8シーケンスは置換文字に変換
- バッファオーバーフローの防止

## 備考

- Readableストリームの内部で自動的に使用される
- lastChar/lastNeed/lastTotal は内部実装の詳細（非公開API）

---

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

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

### 推奨読解順序

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

StringDecoderの内部状態を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | string_decoder.js | `lib/string_decoder.js` | StringDecoderクラス定義 |

**読解のコツ**: `kNativeDecoder`はBufferとして確保された内部状態を保持する。

#### Step 2: コンストラクタを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | string_decoder.js | `lib/string_decoder.js` | StringDecoder（60-67行目） |

**主要処理フロー**:
1. **61行目**: エンコーディング正規化
2. **62-63行目**: 不明エンコーディングでエラー
3. **65-66行目**: 内部バッファ初期化、エンコーディング設定

#### Step 3: write()を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | string_decoder.js | `lib/string_decoder.js` | write()（76-87行目） |

**主要処理フロー**:
- **77-78行目**: 文字列はそのまま返却
- **79-82行目**: ArrayBufferView以外はエラー
- **83-85行目**: kNativeDecoderチェック
- **86行目**: ネイティブdecode関数呼び出し

#### Step 4: end()を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | string_decoder.js | `lib/string_decoder.js` | end()（96-101行目） |

**主要処理フロー**:
- **97行目**: bufがあればwrite()実行
- **98-99行目**: 内部バッファに残りがあればflush

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

```
StringDecoder (lib/string_decoder.js)
    │
    ├─ constructor(encoding)
    │      ├─ normalizeEncoding()
    │      └─ Buffer.alloc(kSize) [内部状態]
    │
    ├─ write(buf)
    │      ├─ 文字列チェック → そのまま返却
    │      ├─ ArrayBufferViewチェック
    │      └─ decode(nativeDecoder, buf)
    │                └─ internalBinding('string_decoder').decode
    │
    ├─ end(buf)
    │      ├─ write(buf) [bufあり時]
    │      └─ flush(nativeDecoder)
    │                └─ internalBinding('string_decoder').flush
    │
    └─ [Legacy] text(buf, offset)
           └─ write(buf.slice(offset))

internalBinding('string_decoder')
    ├─ decode(decoder, buf) - バッファデコード
    ├─ flush(decoder) - 残りバッファフラッシュ
    └─ 定数 (kIncompleteCharactersStart/End, kMissingBytes, etc.)
```

### データフロー図

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

Buffer ─────────────▶ write()
(チャンク1)                │
                          ▼
                    decode()
                          │
                          ├──▶ 完全な文字 ─────────▶ 文字列
                          │
                          └──▶ 不完全文字 ────▶ 内部バッファ保持

Buffer ─────────────▶ write()
(チャンク2)                │
                          ▼
               前回の不完全文字と結合
                          │
                          ▼
                    decode()
                          │
                          └──▶ 完全な文字 ─────────▶ 文字列


                       end()
                          │
                          ▼
                    flush()
                          │
                          └──▶ 残りバッファ ───────▶ 文字列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| string_decoder.js | `lib/string_decoder.js` | ソース | メインエントリポイント |
| internal/util.js | `lib/internal/util.js` | ソース | normalizeEncoding、encodingsMap |
| internal/errors.js | `lib/internal/errors.js` | ソース | エラーコード定義 |
| buffer.js | `lib/buffer.js` | ソース | 内部バッファ確保 |
| src/string_decoder.cc | `src/string_decoder.cc` | C++ソース | ネイティブ実装 |
