# 機能設計書: 60-streams（抽象ストリーム入出力）

## 1. 概要

### 1.1 業務上の目的・背景

streamsモジュールは、ストリームインターフェースとその実装（FileStream、StringStream）を提供する。ファイルやメモリ上の文字列に対して統一的なI/O操作を可能にし、データの読み書きを抽象化する。

### 1.2 機能の利用シーン

- ファイルI/O操作
- メモリ上の文字列操作
- シリアライズ/デシリアライズ
- バイナリデータの読み書き
- テキスト処理（行単位読み込み）

### 1.3 主要な処理内容

1. ストリーム制御: `open`, `close`, `flush`, `atEnd`
2. 位置操作: `setPosition`, `getPosition`
3. データ読み込み: `read`, `readData`, `readLine`, `readAll`
4. データ書き込み: `write`, `writeData`, `writeLine`
5. ピーク: `peek`, `peekData`, `peekLine`
6. 型別読み込み: `readInt8`, `readInt16`, `readInt32`, `readInt64`, `readFloat32`, `readFloat64`

### 1.4 関連するデータ/ファイル

- ファイルシステム上のファイル
- メモリ上の文字列バッファ
- バイナリデータ

### 1.5 バッチ/オンライン区分

オンライン（ファイル/メモリI/O）

## 2. 関連画面

- ファイル読み書きインターフェース
- 設定ファイルパーサ
- データシリアライザ

## 3. 機能種別

- [x] データ操作
- [ ] 帳票出力
- [ ] 外部連携
- [ ] バッチ処理
- [x] リアルタイム処理

## 4. 入力仕様

### 4.1 StreamObj型

| フィールド | 型 | 説明 |
|-----------|-----|------|
| closeImpl | proc | クローズ処理 |
| atEndImpl | proc | 終端判定 |
| setPositionImpl | proc | 位置設定 |
| getPositionImpl | proc | 位置取得 |
| readDataImpl | proc | データ読み込み |
| peekDataImpl | proc | ピーク読み込み |
| writeDataImpl | proc | データ書き込み |
| readLineImpl | proc | 行読み込み |
| readDataStrImpl | proc | 文字列へのデータ読み込み |
| flushImpl | proc | バッファフラッシュ |

### 4.2 FileMode

| モード | 説明 |
|--------|------|
| fmRead | 読み取り専用 |
| fmWrite | 書き込み専用 |
| fmReadWrite | 読み書き（新規作成） |
| fmReadWriteExisting | 読み書き（既存ファイル） |
| fmAppend | 追記 |

### 4.3 入力チェック仕様

| チェック項目 | 内容 | エラー処理 |
|-------------|------|-----------|
| 読み込みバイト数不足 | 要求サイズ分読めない | IOError発生 |
| ストリーム終端 | atEnd時の読み込み | IOError発生 |
| ファイルオープン失敗 | openFileStream失敗 | IOError発生 |

## 5. 出力仕様

### 5.1 StringStream型

| フィールド | 型 | 説明 |
|-----------|-----|------|
| data | string | 内部データバッファ |
| pos | int | 現在位置 |

### 5.2 FileStream型

| フィールド | 型 | 説明 |
|-----------|-----|------|
| f | File | 内部Fileハンドル |

### 5.3 戻り値

| 関数 | 成功時 | 失敗時 |
|------|--------|--------|
| newStringStream | StringStream | - |
| newFileStream(File) | FileStream | - |
| newFileStream(string) | FileStream | nil |
| openFileStream | FileStream | IOError例外 |

## 6. 処理フロー

### 6.1 ストリーム読み込みフロー

```mermaid
flowchart TD
    A[読み込み要求] --> B{ストリーム種別}
    B -->|StringStream| C[data配列から読み込み]
    B -->|FileStream| D[readBuffer呼び出し]
    C --> E[posを更新]
    D --> E
    E --> F{要求サイズ分読めた?}
    F -->|Yes| G[データ返却]
    F -->|No| H{read系関数?}
    H -->|Yes| I[IOError発生]
    H -->|No| J[読めた分を返却]
```

### 6.2 readLine処理フロー

```mermaid
flowchart TD
    A[readLine呼び出し] --> B{readLineImpl?}
    B -->|Yes| C[readLineImpl呼び出し]
    B -->|No| D[フォールバック処理]
    C --> E[結果返却]
    D --> F[readCharループ]
    F --> G{文字判定}
    G -->|CR| H[次の文字読み込み]
    G -->|LF| I[行終了]
    G -->|NULL| J{行データあり?}
    G -->|その他| K[lineに追加]
    H --> I
    J -->|Yes| I
    J -->|No| L[false返却]
    K --> F
    I --> E
```

### 6.3 StringStreamデータフロー

```mermaid
flowchart TD
    A[newStringStream呼び出し] --> B[StringStream作成]
    B --> C[data = 入力文字列]
    C --> D[pos = 0]
    D --> E[各Impl関数を設定]
    E --> F[StringStream返却]

    G[write呼び出し] --> H{pos + len > data.len?}
    H -->|Yes| I[dataを拡張]
    H -->|No| J[dataに書き込み]
    I --> J
    J --> K[posを更新]
```

## 7. ビジネスルール

### 7.1 ストリーム操作

| 操作 | readData | peekData |
|------|----------|----------|
| 位置移動 | あり | なし |
| 戻り値 | 読み込みバイト数 | 読み込みバイト数 |

### 7.2 型別読み込み

| 関数 | サイズ | 備考 |
|------|--------|------|
| readInt8/peekInt8 | 1バイト | - |
| readInt16/peekInt16 | 2バイト | - |
| readInt32/peekInt32 | 4バイト | - |
| readInt64/peekInt64 | 8バイト | - |
| readFloat32/peekFloat32 | 4バイト | - |
| readFloat64/peekFloat64 | 8バイト | - |
| readBool/peekBool | 1バイト | 非0でtrue |

### 7.3 行区切り

| 区切り | 対応 |
|--------|------|
| LF (`\n`) | 対応 |
| CRLF (`\r\n`) | 対応 |
| CR (`\r`) | 部分対応（readLineのみ） |

### 7.4 newFileStream vs openFileStream

| 関数 | ファイルオープン失敗時 |
|------|----------------------|
| newFileStream | nil返却 |
| openFileStream | IOError発生 |

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

該当なし（ファイル/メモリI/O操作のみ）

## 9. エラー処理

### 9.1 エラー一覧

| エラー条件 | 発生関数 | 処理 |
|-----------|---------|------|
| 読み込み不足 | read, readInt*, readFloat* | IOError発生 |
| ストリーム終端 | readLine(string戻り) | IOError発生 |
| ファイルオープン失敗 | openFileStream | IOError発生 |
| 書き込み失敗 | fsWriteData | IOError発生 |

### 9.2 例外型

| 例外 | メッセージ |
|------|-----------|
| IOError | "cannot read from stream" |
| IOError | "cannot write to stream" |
| IOError | "cannot open file stream: {filename}" |

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

該当なし（ストリームI/O操作はトランザクション対象外）

## 11. パフォーマンス要件

| 項目 | 特性 |
|------|------|
| StringStream | メモリ内操作で高速 |
| FileStream | OSバッファリングに依存 |
| readAll | 1024バイト単位でバッファ読み込み |
| readLine | 文字単位読み込み（効率低め） |
| readLineImpl | 実装があれば最適化可能 |

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

### 12.1 バッファ操作

| リスク | 対策 |
|--------|------|
| バッファオーバーフロー | readDataのバッファサイズ確認 |
| 未初期化メモリ読み込み | 戻り値で実際の読み込みサイズを確認 |

### 12.2 ファイル操作

| リスク | 対策 |
|--------|------|
| パストラバーサル | ファイル名の検証 |
| リソースリーク | closeの確実な呼び出し（defer使用） |

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

### 13.1 関連ファイル一覧

| ファイルパス | 概要 | 行数 |
|-------------|------|------|
| lib/pure/streams.nim | ストリームモジュール | 約1548行 |
| lib/std/syncio.nim | ファイルI/O（依存） | - |

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

```
streams.nim
├── Stream/StreamObj型 (112-145行)
├── 基本操作
│   ├── close (176-195行)
│   ├── flush (147-174行)
│   ├── atEnd (197-209行)
│   ├── setPosition (211-221行)
│   └── getPosition (223-232行)
├── データ読み込み
│   ├── readData (234-247行)
│   ├── readDataStr (249-265行)
│   ├── readAll (280-311行)
│   ├── read[T] (414-431行)
│   ├── readChar (452-471行)
│   ├── readLine (1002-1043行, 1076-1104行)
│   ├── readStr (957-973行, 962-973行)
│   └── 型別read (544-882行)
├── ピーク
│   ├── peekData (313-327行)
│   ├── peek[T] (433-450行)
│   ├── peekChar (473-490行)
│   ├── peekLine (1045-1074行, 1106-1126行)
│   └── 型別peek (517-903行)
├── データ書き込み
│   ├── writeData (329-348行)
│   ├── write[T] (350-366行)
│   ├── write(string) (368-386行)
│   ├── write(varargs) (388-398行)
│   └── writeLine (400-412行)
├── StringStream (1147-1322行)
│   ├── StringStreamObj (1150-1154行)
│   ├── ssAtEnd (1207-1209行)
│   ├── ssSetPosition (1211-1213行)
│   ├── ssGetPosition (1215-1217行)
│   ├── ssReadData (1236-1250行)
│   ├── ssPeekData (1252-1265行)
│   ├── ssWriteData (1267-1281行)
│   ├── ssClose (1283-1285行)
│   └── newStringStream (1287-1322行)
├── FileStream (1324-1476行)
│   ├── FileStreamObj (1329-1333行)
│   ├── fsClose (1335-1338行)
│   ├── fsFlush (1339行)
│   ├── fsAtEnd (1340行)
│   ├── fsSetPosition (1341行)
│   ├── fsGetPosition (1342行)
│   ├── fsReadData (1344-1345行)
│   ├── fsReadDataStr (1347-1348行)
│   ├── fsPeekData (1350-1353行)
│   ├── fsWriteData (1355-1357行)
│   ├── fsReadLine (1359-1360行)
│   ├── newFileStream(File) (1362-1403行)
│   ├── newFileStream(string) (1405-1442行)
│   └── openFileStream (1444-1476行)
└── lines iterator (1128-1145行)
```

### 13.3 データフロー図

```
[データソース]
       │
       ├─ ファイル ─────────────────┐
       └─ 文字列 ───────────────────┤
                                    │
                                    ▼
                            ┌─────────────┐
                            │ Stream抽象  │
                            │  (StreamObj) │
                            └─────────────┘
                                    │
              ┌─────────────────────┼─────────────────────┐
              ▼                     ▼                     ▼
       ┌─────────────┐       ┌─────────────┐       ┌─────────────┐
       │ FileStream   │       │StringStream │       │カスタム実装  │
       └─────────────┘       └─────────────┘       └─────────────┘
              │                     │                     │
              └─────────────────────┴─────────────────────┘
                                    │
                                    ▼
                            [共通API]
                            read/write
                            readLine
                            getPosition
                            setPosition
                            close
```

### 13.4 読み解くべき重要なコード

1. **StreamObj型定義（116-145行）**: ストリームインターフェース
2. **newStringStream（1287-1322行）**: StringStreamの初期化
3. **newFileStream（1362-1403行）**: FileStreamの初期化
4. **readLine（1002-1043行）**: 行読み込みロジック
5. **read[T]（414-431行）**: ジェネリック読み込み

### 13.5 推奨リーディング順序

1. Stream/StreamObj型定義（112-145行）- インターフェース理解
2. 基本操作（close, flush, atEnd, setPosition, getPosition）
3. newStringStream/newFileStream - 具体的な実装
4. read/write系関数 - データ操作
5. readLine/lines - テキスト処理
6. 型別read/peek - バイナリ処理
