# 機能設計書 65-バイト検索

## 概要

本ドキュメントは、Nushellにおけるバイト検索機能（bytes starts-with, bytes ends-with, bytes index-of）の設計を記述する。バイナリデータ内でのパターンマッチングと位置検索を提供する。

### 本機能の処理概要

バイト検索機能は、バイナリデータに対してパターンの検索・マッチングを行う。先頭・末尾の一致確認や、パターンの出現位置検索により、バイナリデータの解析や検証を支援する。

**業務上の目的・背景**：バイナリファイルのフォーマット検証（マジックナンバー確認）、バイナリプロトコルの解析、特定のバイトシーケンスの検出など、バイナリデータの検査が必要な場面がある。本機能により、シェルスクリプト内でバイナリパターンマッチングが可能となる。

**機能の利用シーン**：
- ファイルのマジックナンバー（ヘッダシグネチャ）確認
- バイナリファイルフォーマットの検証
- バイナリプロトコルのパース
- 特定のバイトシーケンスの位置特定
- バイナリデータの整合性チェック

**主要な処理内容**：
1. `bytes starts-with` - 指定パターンで始まるか確認
2. `bytes ends-with` - 指定パターンで終わるか確認
3. `bytes index-of` - 指定パターンの位置を検索

**関連システム・外部連携**：外部システムとの直接連携はない。

**権限による制御**：特別な権限制御はなく、すべてのユーザーが実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | バイナリビュー | 参照画面 | バイナリデータの可視化表示 |

## 機能種別

データ検索 / パターンマッチング

## 入力仕様

### 入力パラメータ

#### bytes starts-with / bytes ends-with

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pattern | Binary | Yes | 検索パターン | - |
| rest | CellPath | No | 対象セルパス | 有効なセルパス |

#### bytes index-of

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pattern | Binary | Yes | 検索パターン | - |
| --all, -a | Switch | No | すべての出現位置を返す | - |
| --end, -e | Switch | No | 末尾から検索 | - |
| rest | CellPath | No | 対象セルパス | 有効なセルパス |

### 入力データソース

- **パイプライン入力**: Binary, ByteStream, Table, Record
- **ByteStream**: starts-with/ends-withでストリーミング処理対応

## 出力仕様

### 出力データ

| コマンド | 出力型 | 説明 |
|---------|--------|------|
| bytes starts-with | Bool | パターンで始まる場合 true |
| bytes ends-with | Bool | パターンで終わる場合 true |
| bytes index-of | Int | パターンの位置（見つからない場合 -1） |
| bytes index-of --all | List[Int] | すべての出現位置のリスト |

### 出力先

パイプラインへの出力（PipelineData）。

## 処理フロー

### 処理シーケンス

```
1. コマンドの引数解析
   └─ パターン、フラグ、セルパスを取得

2. 入力データの判定
   └─ ByteStream の場合は特別処理
   └─ Binary の場合は直接処理
   └─ Table/Record の場合は operate() でセルパス処理

3. パターンマッチング
   └─ starts-with: 先頭バイトとパターンを比較
   └─ ends-with: 末尾バイトとパターンを比較
   └─ index-of: windows() でスライディングウィンドウ検索

4. 結果の返却
   └─ Bool または Int/List[Int] として出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{コマンド種別}
    B -->|starts-with| C{ByteStream?}
    B -->|ends-with| D{ByteStream?}
    B -->|index-of| E[バイナリ処理]
    C -->|Yes| F[先頭バイト読み取り]
    C -->|No| G[val.starts_with]
    D -->|Yes| H[末尾バイト保持しながら読み取り]
    D -->|No| I[val.ends_with]
    E --> J{--all?}
    J -->|Yes| K[全位置検索]
    J -->|No| L[最初の位置検索]
    F --> M[パターン比較]
    G --> M
    H --> N[パターン比較]
    I --> N
    K --> O[Value::list]
    L --> P[Value::int]
    M --> Q[Value::bool]
    N --> Q
    O --> R[PipelineData返却]
    P --> R
    Q --> R
    R --> S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 空パターン | 空のパターンは常に true を返す | starts-with/ends-with |
| BR-002 | 見つからない場合 | index-of は -1 を返す | パターンが存在しない場合 |
| BR-003 | 検索方向 | --end フラグで末尾から検索 | index-of |
| BR-004 | 全検索 | --all フラグですべての出現位置を返す | index-of |
| BR-005 | 重複なし | --all は重複しない位置のみ返す | index-of --all |

### 計算ロジック

- **starts-with**: `val.starts_with(&pattern)` または ByteStream の先頭バイト比較
- **ends-with**: `val.ends_with(&pattern)` または ByteStream の末尾バイト保持比較
- **index-of**: `windows(pattern.len())` でスライディングウィンドウ検索、`position()` で位置取得

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| OnlySupportsThisInputType | 型エラー | Binary以外の入力 | Binary を入力 |
| IoError | IOエラー | ByteStream読み取りエラー | 入力ストリームを確認 |

### リトライ仕様

リトライは不要。

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

本機能はトランザクション管理を行わない。

## パフォーマンス要件

- パターンマッチングは O(n) で完了（n = 入力バイト数）
- ByteStream の ends-with は全データ読み取りが必要（VecDeque で末尾保持）
- 大容量データでも starts-with は先頭のみ読み取りで高速

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

- 特別なセキュリティ考慮事項なし

## 備考

- ByteStream の ends-with は全データを読み取る必要があるため、大容量データでは注意

---

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

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

### 推奨読解順序

#### Step 1: starts-withを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | starts_with.rs | `crates/nu-command/src/bytes/starts_with.rs` | bytes starts-with 実装 |

**主要処理フロー**:
- **51-85行目**: `run()` メソッド
- **63-77行目**: ByteStream の場合、パターン長だけ先頭を読み取り
- **65-66行目**: 空パターンは true
- **79-84行目**: operate() で各値を処理
- **108-124行目**: `starts_with()` 関数で `val.starts_with(&pattern)`

#### Step 2: ends-withを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ends_with.rs | `crates/nu-command/src/bytes/ends_with.rs` | bytes ends-with 実装 |

**主要処理フロー**:
- **53-108行目**: `run()` メソッド
- **65-100行目**: ByteStream の場合、VecDeque で末尾バイトを保持
- **74行目**: パターン長の容量で VecDeque を作成
- **75-99行目**: 全データ読み取りながら末尾を保持
- **131-147行目**: `ends_with()` 関数

#### Step 3: index-ofを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index_of.rs | `crates/nu-command/src/bytes/index_of.rs` | bytes index-of 実装 |

**主要処理フロー**:
- **58-75行目**: `run()` メソッド
- **68-73行目**: Arguments 構造体で pattern, end, all フラグを保持
- **120-161行目**: `index_of_impl()` 関数
- **139-160行目**: 単一位置検索（--end で逆順）
- **142-148行目**: `windows(pattern.len())` でスライディングウィンドウ
- **163-199行目**: `search_all_index()` 関数（--all の場合）

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

```
bytes starts-with (starts_with.rs)
    │
    ├─ ByteStream入力
    │      └─ reader.take(pattern.len()).read_to_end()
    │      └─ start == pattern
    │
    └─ Binary入力
           └─ operate(starts_with, ...)
                  └─ val.starts_with(&pattern)

bytes ends-with (ends_with.rs)
    │
    ├─ ByteStream入力
    │      └─ VecDeque で末尾保持しながら読み取り
    │      └─ end == pattern
    │
    └─ Binary入力
           └─ operate(ends_with, ...)
                  └─ val.ends_with(&pattern)

bytes index-of (index_of.rs)
    │
    └─ Binary入力
           └─ operate(index_of, ...)
                  └─ index_of_impl()
                         │
                         ├─ --all: search_all_index()
                         │      └─ 全位置をリストで返す
                         │
                         └─ 通常: windows().position()
                                └─ 最初の位置を返す
```

### データフロー図

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

Binary ────────────▶ starts_with/ends_with ─────────▶ Bool
                           │
ByteStream ────────▶ 先頭/末尾読み取り ─────────────▶ Bool
                           │
Binary ────────────▶ index_of_impl ─────────────────▶ Int / List[Int]
                           │
                           ▼
                    PipelineData返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| starts_with.rs | `crates/nu-command/src/bytes/starts_with.rs` | ソース | bytes starts-with 実装 |
| ends_with.rs | `crates/nu-command/src/bytes/ends_with.rs` | ソース | bytes ends-with 実装 |
| index_of.rs | `crates/nu-command/src/bytes/index_of.rs` | ソース | bytes index-of 実装 |
| mod.rs | `crates/nu-command/src/bytes/mod.rs` | ソース | モジュール定義 |
