# 機能設計書 13-zlib

## 概要

本ドキュメントは、Node.jsのzlibモジュール（圧縮・解凍機能）の機能設計を記述したものである。

### 本機能の処理概要

zlib機能は、gzip、deflate、brotli、zstd形式でのデータ圧縮・解凍機能を提供する。ストリームベースのAPIと同期/非同期の便利関数を提供し、大容量データの効率的な圧縮処理を可能にする。

**業務上の目的・背景**：ネットワーク転送量の削減、ストレージ容量の節約、HTTPレスポンスの圧縮（Content-Encoding）など、様々な場面でデータ圧縮が必要となる。zlibはこれらの要件を満たすための標準的な圧縮機能を提供する。

**機能の利用シーン**：
- HTTP圧縮（gzip/deflate/br）
- ファイルアーカイブの作成・展開
- データベースバックアップの圧縮
- ログファイルの圧縮保存
- APIレスポンスの帯域最適化
- 大容量データの転送効率化

**主要な処理内容**：
1. gzip/gunzip: gzip形式の圧縮・解凍
2. deflate/inflate: deflate形式の圧縮・解凍
3. deflateRaw/inflateRaw: ヘッダなしdeflate
4. brotliCompress/brotliDecompress: Brotli形式の圧縮・解凍
5. zstdCompress/zstdDecompress: Zstandard形式の圧縮・解凍
6. unzip: 自動形式検出での解凍
7. crc32: CRC32チェックサム計算

**関連システム・外部連携**：
- http/https: Content-Encoding圧縮
- stream: ストリームベースの圧縮処理
- fs: 圧縮ファイルの読み書き
- buffer: 圧縮データの入出力

**権限による制御**：特になし。zlibはユーザーランドで自由に使用可能。

## 関連画面

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

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

## 機能種別

データ処理 / 圧縮・解凍

## 入力仕様

### 入力パラメータ

#### 共通オプション

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| chunkSize | number | No | 処理チャンクサイズ | >= Z_MIN_CHUNK (64) |
| flush | number | No | フラッシュ動作 | Z_NO_FLUSH〜Z_FINISH |
| finishFlush | number | No | 終了時フラッシュ | デフォルトZ_FINISH |
| maxOutputLength | number | No | 最大出力長 | 1〜kMaxLength |

#### Zlib固有オプション（gzip/deflate/inflate等）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| windowBits | number | No | ウィンドウサイズ | 8〜15 (gzipは9〜15) |
| level | number | No | 圧縮レベル | -1〜9 |
| memLevel | number | No | メモリ使用量 | 1〜9 |
| strategy | number | No | 圧縮戦略 | Z_DEFAULT_STRATEGY等 |
| dictionary | Buffer | No | カスタム辞書 | - |

#### Brotli固有オプション

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| params | Object | No | Brotliパラメータ | BROTLI_PARAM_*定数 |

#### Zstd固有オプション

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| params | Object | No | Zstdパラメータ | ZSTD_c_*/ZSTD_d_*定数 |
| pledgedSrcSize | number | No | 予想入力サイズ | - |
| dictionary | Buffer | No | Zstd辞書 | - |

### 入力データソース

- Buffer/Uint8Array（圧縮/解凍対象データ）
- ストリーム（pipe経由）
- 文字列（同期関数では自動変換）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 圧縮/解凍データ | Buffer | 処理結果データ |
| ストリーム | Transform | ストリームとしての出力 |

### 出力先

- コールバック関数（非同期API）
- 戻り値（同期API）
- pipe先ストリーム（ストリームAPI）

## 処理フロー

### 処理シーケンス

```
1. オプション検証
   └─ chunkSize、flush、level等の検証
2. エンジン初期化
   └─ Zlib/Brotli/Zstdハンドル作成
3. データ処理
   └─ チャンク単位で圧縮/解凍
   └─ バックプレッシャー制御
4. 出力生成
   └─ 圧縮/解凍データをバッファリング
5. 終了処理
   └─ フラッシュ、リソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[入力データ] --> B{処理種別}
    B -->|ストリーム| C[Transform継承クラス]
    B -->|非同期| D[zlibBuffer]
    B -->|同期| E[zlibBufferSync]

    C --> F{圧縮形式}
    D --> F
    E --> F

    F -->|zlib| G[Zlib処理]
    F -->|brotli| H[Brotli処理]
    F -->|zstd| I[Zstd処理]

    G --> J[ネイティブbinding.Zlib]
    H --> K[ネイティブBrotliEncoder/Decoder]
    I --> L[ネイティブZstdCompress/Decompress]

    J --> M[processChunk/processChunkSync]
    K --> M
    L --> M

    M --> N[出力バッファ]
    N --> O{完了?}
    O -->|No| M
    O -->|Yes| P[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 最大出力制限 | maxOutputLength超過時にエラー | ERR_BUFFER_TOO_LARGE |
| BR-002 | チャンクサイズ | chunkSize < 64でエラー | Z_MIN_CHUNK |
| BR-003 | 圧縮レベル | level -1〜9（-1はデフォルト） | Zlib系 |
| BR-004 | 自動形式検出 | Unzipはgzip/deflateを自動判定 | Unzip使用時 |
| BR-005 | 末尾ゴミデータ | rejectGarbageAfterEnd=trueで拒否 | 厳密チェック時 |

### 計算ロジック

#### CRC32計算
```javascript
function crc32(data, value = 0) {
  if (typeof data !== 'string' && !isArrayBufferView(data)) {
    throw new ERR_INVALID_ARG_TYPE('data', ...);
  }
  validateUint32(value, 'value');
  return crc32Native(data, value);
}
```

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

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR_BUFFER_TOO_LARGE | RangeError | 出力がmaxOutputLength超過 | 制限値を増加または分割処理 |
| ERR_BROTLI_INVALID_PARAM | RangeError | 不正なBrotliパラメータ | 有効なパラメータを指定 |
| ERR_ZSTD_INVALID_PARAM | RangeError | 不正なZstdパラメータ | 有効なパラメータを指定 |
| ERR_INVALID_ARG_TYPE | TypeError | 引数の型が不正 | 正しい型を使用 |
| ERR_OUT_OF_RANGE | RangeError | パラメータ範囲外 | 範囲内の値を使用 |
| ERR_TRAILING_JUNK_AFTER_STREAM_END | Error | 末尾に不正データ | rejectGarbageAfterEnd時 |
| Z_DATA_ERROR | Error | 不正な圧縮データ | 正しいデータを入力 |
| Z_MEM_ERROR | Error | メモリ不足 | リソース解放 |

### リトライ仕様

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

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

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

## パフォーマンス要件

- デフォルトチャンクサイズ: 16KB (Z_DEFAULT_CHUNK)
- 圧縮レベル0（無圧縮）〜9（最大圧縮）で速度と圧縮率のトレードオフ
- Brotliは圧縮率高いが処理速度は遅い
- Zstdは高速かつ高圧縮率

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

- 圧縮爆弾（Zip bomb）対策としてmaxOutputLengthを設定
- 信頼できないデータの解凍時は出力サイズを制限
- メモリ使用量制限のためmemLevelを調整可能

## 備考

- Brotliは Node.js 10.16.0 で追加
- Zstd は Node.js 21.0.0 で追加（実験的）
- DEP0184: クラスの直接呼び出しは非推奨（createXxx関数を使用）

---

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

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

### 推奨読解順序

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

圧縮エンジンの継承関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | zlib.js | `lib/zlib.js` | エクスポート構造、クラス定義 |

**読解のコツ**: ZlibBase → Zlib → 各圧縮クラス（Gzip等）の継承関係を把握する。

#### Step 2: 基底クラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | zlib.js | `lib/zlib.js` | ZlibBase（210-275行目） |

**主要処理フロー**:
1. **210-275行目**: ZlibBaseコンストラクタ（Transform継承）
2. **292-295行目**: reset()
3. **303-305行目**: _flush()
4. **377-390行目**: _transform()

#### Step 3: Zlib系処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | zlib.js | `lib/zlib.js` | Zlib（620-688行目）、Deflate/Inflate等 |

**主要処理フロー**:
- **620-688行目**: Zlibコンストラクタ（windowBits/level/memLevel/strategy設定）
- **722-729行目**: Deflate
- **731-738行目**: Inflate
- **740-747行目**: Gzip
- **749-756行目**: Gunzip

#### Step 4: Brotli/Zstd処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | zlib.js | `lib/zlib.js` | Brotli（812-860行目）、Zstd（868-936行目） |

**主要処理フロー**:
- **812-842行目**: Brotliクラス（params処理）
- **868-908行目**: Zstdクラス（ES6 class構文）

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

```
zlib (lib/zlib.js)
    │
    ├─ ZlibBase (Transform継承)
    │       │
    │       ├─ Zlib (windowBits/level/memLevel/strategy)
    │       │     ├─ Deflate / Inflate
    │       │     ├─ Gzip / Gunzip
    │       │     ├─ DeflateRaw / InflateRaw
    │       │     └─ Unzip
    │       │
    │       ├─ Brotli
    │       │     ├─ BrotliCompress
    │       │     └─ BrotliDecompress
    │       │
    │       └─ Zstd
    │             ├─ ZstdCompress
    │             └─ ZstdDecompress
    │
    ├─ 便利関数（非同期）
    │       ├─ deflate / inflate
    │       ├─ gzip / gunzip
    │       ├─ deflateRaw / inflateRaw
    │       ├─ brotliCompress / brotliDecompress
    │       └─ zstdCompress / zstdDecompress
    │
    ├─ 便利関数（同期）
    │       ├─ deflateSync / inflateSync
    │       ├─ gzipSync / gunzipSync
    │       └─ ...
    │
    └─ crc32

internalBinding('zlib')
    ├─ Zlib (ネイティブ)
    ├─ BrotliEncoder / BrotliDecoder
    ├─ ZstdCompress / ZstdDecompress
    └─ crc32
```

### データフロー図

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

Buffer ─────────▶ zlibBuffer()
                      │
                      ▼
               new Gzip(opts)
                      │
                      ▼
               engine.write(data)
                      │
                      ▼
               processChunk()  ◀──── binding.Zlib.write()
                      │
                      ▼
               コールバック実行 ────▶ 圧縮データ


ストリーム ────▶ pipe(gzip) ────▶ pipe(output)
                      │
                      ▼
               _transform()
                      │
                      ▼
               processChunk() ────▶ push(chunk)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| zlib.js | `lib/zlib.js` | ソース | メインエントリポイント |
| internal/buffer.js | `lib/internal/buffer.js` | ソース | FastBuffer（出力バッファ） |
| stream.js | `lib/stream.js` | ソース | Transform基底クラス |
| internal/validators.js | `lib/internal/validators.js` | ソース | パラメータ検証 |
| internal/errors.js | `lib/internal/errors.js` | ソース | エラーコード定義 |
| src/node_zlib.cc | `src/node_zlib.cc` | C++ソース | ネイティブ実装 |
