# 機能設計書 32-StringReader

## 概要

本ドキュメントは、VBCorLibライブラリにおけるStringReaderクラスの機能設計について記述する。StringReaderは、文字列をストリームとして読み込むためのテキストリーダークラスである。

### 本機能の処理概要

**業務上の目的・背景**：アプリケーション開発において、文字列データを行単位や文字単位で順次読み込む処理が必要となる場面は多い。StringReaderは、メモリ上の文字列をファイルストリームと同様のインターフェースで読み込むことを可能にし、ファイルI/Oとメモリ上の文字列処理を統一的に扱えるようにする。これにより、テスト容易性の向上やコードの再利用性が高まる。

**機能の利用シーン**：複数行の文字列を行単位で処理する場合、設定データやCSVデータの解析処理、テスト時のモック入力として使用する場合、StreamReaderと同一インターフェースで処理を行いたい場合など、文字列をストリーム的に読み込む必要があるすべての場面で利用される。

**主要な処理内容**：
1. 文字列の文字単位読み込み（Read、Peek）
2. 文字列の行単位読み込み（ReadLine）
3. 文字列の残り全体読み込み（ReadToEnd）
4. 文字列のブロック読み込み（ReadBlock）
5. リーダーのクローズ処理（CloseReader）

**関連システム・外部連携**：TextReaderインターフェースを実装しており、StreamReaderと同様のインターフェースで使用可能。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は画面を持たないライブラリクラスである |

## 機能種別

データ読み込み処理（テキストI/O）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| s | String | Yes | 読み込み対象の文字列 | - |
| CopyString | Boolean | No | 文字列をコピーするかどうか | - |
| Buffer | Integer() | Yes | ReadBlock用の出力バッファ | 有効な配列であること |
| Index | Long | Yes | ReadBlock用の開始インデックス | 配列範囲内であること |
| Count | Long | Yes | ReadBlock用の読み込み文字数 | 0以上であること |

### 入力データソース

コンストラクタで指定される文字列データ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 文字コード | Long | ReadおよびPeekで返される文字のUnicodeコード値（-1は終端） |
| 行文字列 | String | ReadLineで返される1行分の文字列 |
| 残り文字列 | String | ReadToEndで返される残りの文字列全体 |
| 読み込み数 | Long | ReadBlockで実際に読み込んだ文字数 |

### 出力先

呼び出し元のプログラムに戻り値として返される

## 処理フロー

### 処理シーケンス

```
1. StringReader初期化
   └─ 文字列を内部配列として保持
2. Read/Peek操作
   └─ 現在位置の文字を返す（Readは位置を進める）
3. ReadLine操作
   └─ CR/LFを検索して行を返す
   └─ CR-LFの連続は1つの改行として扱う
4. ReadToEnd操作
   └─ 現在位置から終端までを返す
5. CloseReader
   └─ 閉じた状態としてマーク
```

### フローチャート

```mermaid
flowchart TD
    A[StringReader生成] --> B[文字列をInteger配列に変換]
    B --> C{読み込み操作}
    C -->|Peek| D[現在位置の文字を返す]
    C -->|Read| E[現在位置の文字を返し位置を進める]
    C -->|ReadLine| F{改行文字を検索}
    C -->|ReadToEnd| G[残り全体を返す]
    F -->|見つかった| H[改行までの文字列を返す]
    F -->|見つからない| I[残り全体を返す]
    D --> J{終端?}
    E --> J
    J -->|Yes| K[-1を返す]
    J -->|No| L[文字コードを返す]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 改行文字の扱い | CR(13)またはLF(10)が改行として認識される | ReadLine呼び出し時 |
| BR-002 | CR-LF連続の扱い | CRの直後にLFがある場合、1つの改行として扱う | ReadLine呼び出し時 |
| BR-003 | 文字コードの符号 | &H8000以上の文字も正の値として返す | Read/Peek呼び出し時 |
| BR-004 | 終端表現 | 文字列終端に達した場合は-1を返す | Read/Peek呼び出し時 |

### 計算ロジック

**文字コードの正値変換**:
```vb
AsWord(Peek) = mChars(mPosition)  ' Integerを正のLongに変換
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ObjectDisposed_ReaderClosed | ObjectDisposedException | リーダーが閉じている状態でメソッド呼び出し | リーダーを再度生成する |

### リトライ仕様

リトライ処理は実装されていない。

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

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

## パフォーマンス要件

- 文字列を内部でInteger配列として保持することで高速なランダムアクセスを実現
- CopyString=Falseの場合、元の文字列を直接参照して効率化

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

- 入力文字列の内容に関する検証は行わない
- 機密データを含む場合は呼び出し元で適切な管理が必要

## 備考

- TextReaderインターフェースを実装しているため、多態的な利用が可能
- StreamReaderとの互換性を意識した設計

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | StringReader.cls | `Source/CorLib/System.IO/StringReader.cls` | 48-53行目のプライベート変数宣言を確認 |

**読解のコツ**: mString（元の文字列）、mChars（文字配列）、mPosition（現在位置）、mLength（文字列長）が主要な状態変数。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | StringReader.cls | `Source/CorLib/System.IO/StringReader.cls` | 219-229行目のInit関数でコンストラクタ処理を確認 |

**主要処理フロー**:
1. **220-225行目**: CopyStringフラグによる文字列コピーまたはポインタ参照の分岐
2. **227-228行目**: 文字列長の設定と文字配列の割り当て

#### Step 3: 読み込み処理の核心を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | StringReader.cls | `Source/CorLib/System.IO/StringReader.cls` | 73-81行目のPeek関数 |
| 3-2 | StringReader.cls | `Source/CorLib/System.IO/StringReader.cls` | 92-98行目のRead関数 |
| 3-3 | StringReader.cls | `Source/CorLib/System.IO/StringReader.cls` | 131-170行目のReadLine関数 |

**主要処理フロー**:
- **77行目**: AsWordによるIntegerからLongへの符号なし変換
- **142-146行目**: CR/LFの検出ループ
- **157-168行目**: CR-LF連続の処理

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

```
StringReader
    │
    ├─ Init (コンストラクタ)
    │      └─ AllocChars（文字配列割り当て）
    │
    ├─ Peek
    │      └─ VerifyIsOpen
    │
    ├─ Read
    │      └─ Peek呼び出し
    │
    ├─ ReadLine
    │      ├─ VerifyIsOpen
    │      └─ Mid$（部分文字列取得）
    │
    ├─ ReadBlock
    │      ├─ ValidateArrayRange
    │      ├─ VerifyIsOpen
    │      └─ CopyMemory（メモリコピー）
    │
    ├─ ReadToEnd
    │      ├─ VerifyIsOpen
    │      └─ Mid$（残り文字列取得）
    │
    └─ CloseReader
           └─ mIsClosed = True
```

### データフロー図

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

文字列 ─────────▶ Init
                     │
                     ▼
              Integer配列に変換
                     │
                     ▼
              Read/ReadLine等 ─────────▶ 文字/行/文字列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| StringReader.cls | `Source/CorLib/System.IO/StringReader.cls` | ソース | StringReaderクラス本体 |
| TextReader.cls | `Source/CorLib/System.IO/TextReader.cls` | ソース | 実装インターフェース |
| StreamReader.cls | `Source/CorLib/System.IO/StreamReader.cls` | ソース | 関連クラス（同インターフェース） |
