# 機能設計書 15-Buffer

## 概要

本ドキュメントは、VBCorLibライブラリにおけるプリミティブ型配列のバイト操作機能「Buffer」クラスの機能設計について記述する。

### 本機能の処理概要

Bufferクラスは、プリミティブ型配列をバイト単位で操作する機能を提供する静的クラスである。.NET FrameworkのSystem.Bufferクラスと互換性のあるAPIを持ち、配列間のブロックコピー、バイト単位でのアクセス、配列のバイト長取得などの低レベル操作を実現する。

**業務上の目的・背景**：バイナリデータ処理、暗号化、圧縮、ネットワーク通信など、バイトレベルでの配列操作が必要な場面で使用される。VBAには標準でこのような機能がないため、Bufferクラスがこのギャップを埋める。

**機能の利用シーン**：
- バイナリデータの高速コピー
- 配列の部分コピー
- 異なる型の配列間でのバイト転送
- メモリバッファの操作
- 配列のバイトサイズ取得

**主要な処理内容**：
1. ブロックコピー（BlockCopy）- 配列間のバイト単位コピー
2. バイト長取得（ByteLength）- 配列のバイトサイズ計算
3. バイト単位アクセス（GetByte、SetByte）- 個別バイトの読み書き

**関連システム・外部連携**：暗号化クラス、ストリームクラス、MemoryStreamなどと組み合わせて使用される。

**権限による制御**：本機能には権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Simply VB Unit Runner | 主画面 | テストスイート内のBufferテスト（BufferTests）の実行 |

## 機能種別

メモリ操作処理 / ユーティリティ機能

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Src | Array | Yes | BlockCopyのコピー元配列 | プリミティブ型の1次元配列 |
| SrcOffset | Long | Yes | コピー元のバイトオフセット | 0以上、配列範囲内 |
| Dst | Array | Yes | BlockCopyのコピー先配列 | プリミティブ型の1次元配列 |
| DstOffset | Long | Yes | コピー先のバイトオフセット | 0以上、配列範囲内 |
| Count | Long | Yes | コピーするバイト数 | 0以上、両配列の範囲内 |
| Arr | Array | Yes | ByteLength/GetByte/SetByteの対象配列 | プリミティブ型配列 |
| Index | Long | Yes | GetByte/SetByteのバイトインデックス | 0以上、配列範囲内 |
| Value | Byte | Yes | SetByteで設定する値 | 0-255 |

### 入力データソース

プログラムからの直接呼び出し（パラメータ指定）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ByteLength戻り値 | Long | 配列のバイト長 |
| GetByte戻り値 | Byte | 指定位置のバイト値 |

### 出力先

呼び出し元への戻り値として返却、またはコピー先配列への直接書き込み

## 処理フロー

### 処理シーケンス

```
1. BlockCopy呼び出し
   └─ 引数バリデーション
   └─ ソース配列のポインタ取得
   └─ 宛先配列のポインタ取得
   └─ CopyMemoryでバイトコピー

2. ByteLength呼び出し
   └─ 配列バリデーション
   └─ 要素数 × 要素サイズを計算
   └─ バイト長を返却

3. GetByte呼び出し
   └─ 配列・インデックスバリデーション
   └─ 配列先頭ポインタ + インデックスからバイト読み取り
   └─ バイト値を返却

4. SetByte呼び出し
   └─ 配列・インデックスバリデーション
   └─ 配列先頭ポインタ + インデックスにバイト書き込み
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{メソッド種別}
    B -->|BlockCopy| C[配列バリデーション]
    C --> D{プリミティブ型?}
    D -->|No| E[ArgumentException]
    D -->|Yes| F{範囲内?}
    F -->|No| G[ArgumentOutOfRangeException]
    F -->|Yes| H[CopyMemory実行]
    H --> I[終了]
    B -->|ByteLength| J[配列バリデーション]
    J --> K{プリミティブ型?}
    K -->|No| L[ArgumentException]
    K -->|Yes| M[要素数 × サイズ計算]
    M --> N[バイト長返却]
    N --> I
    B -->|GetByte| O[配列・インデックスバリデーション]
    O --> P{範囲内?}
    P -->|No| Q[ArgumentOutOfRangeException]
    P -->|Yes| R[バイト読み取り]
    R --> S[バイト値返却]
    S --> I
    B -->|SetByte| T[配列・インデックスバリデーション]
    T --> U{範囲内?}
    U -->|No| V[ArgumentOutOfRangeException]
    U -->|Yes| W[バイト書き込み]
    W --> I
    E --> I
    G --> I
    L --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | プリミティブ型制約 | 操作対象はプリミティブ型配列（Byte、Integer、Long、Single、Double、Currency、Date）のみ | 全メソッド |
| BR-002 | 1次元配列制約 | 操作対象は1次元配列のみ | 全メソッド |
| BR-003 | バイトアラインメント | オフセットとカウントはバイト単位で指定 | BlockCopy |
| BR-004 | 重複領域の挙動 | ソースと宛先の領域が重複しても正しくコピーされる | BlockCopy |

### 計算ロジック

**ByteLength計算**:
```
ByteLength = (UBound(Arr) - LBound(Arr) + 1) × ElementSize(Arr)

ElementSize:
  vbByte: 1
  vbInteger: 2
  vbLong: 4
  vbSingle: 4
  vbDouble: 8
  vbCurrency: 8
  vbDate: 8
```

**バイトインデックス計算**:
```
PointerAddress = VarPtr(Arr(LBound(Arr))) + Index
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentNullException | 配列がNullまたは未初期化 | 初期化済み配列を指定 |
| - | ArgumentException | 非プリミティブ型配列 | プリミティブ型配列を使用 |
| - | ArgumentOutOfRangeException | オフセットが負の値 | 0以上の値を指定 |
| - | ArgumentException | カウントが範囲外 | 有効な範囲を指定 |
| - | RankException | 多次元配列 | 1次元配列を使用 |

### リトライ仕様

メモリ操作処理であるため、リトライは不要。

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

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

## パフォーマンス要件

- BlockCopy: CopyMemory APIを使用し、高速なメモリコピーを実現
- ByteLength: O(1)の定数時間
- GetByte/SetByte: O(1)の定数時間

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

- バッファオーバーフローを防ぐため、全メソッドで範囲チェックを実施
- センシティブなデータを扱う場合は、使用後にバッファをクリアすることを推奨

## 備考

- 内部でCopyMemory APIを使用しているため、VBAのネイティブ操作より高速
- String配列は参照型のため、Bufferでは操作不可

---

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

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

### 推奨読解順序

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

Bufferクラスはステートレスな静的クラスである。重要なのは配列のメモリレイアウトとSafeArray構造の理解である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Buffer.cls | `Source/CorLib/System/Buffer.cls` | クラス構造、静的クラスとしての設計 |

**読解のコツ**: VB6/VBAの配列はSafeArray構造で管理される。pvDataメンバが実データへのポインタを持つ。

#### Step 2: BlockCopyを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Buffer.cls | `Source/CorLib/System/Buffer.cls` | BlockCopyメソッドの実装 |

**主要処理フロー**:
1. **60-90行目**: BlockCopyメソッド - バリデーションとCopyMemory呼び出し
2. **62-65行目**: 配列のプリミティブ型チェック
3. **70-80行目**: オフセットとカウントの範囲チェック
4. **85行目**: CopyMemory API呼び出し

#### Step 3: ByteLengthを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Buffer.cls | `Source/CorLib/System/Buffer.cls` | ByteLengthメソッドの実装 |

**主要処理フロー**:
- **100-115行目**: ByteLengthメソッド
- **105行目**: 要素数の取得
- **110行目**: 要素サイズの取得（VarTypeから計算）
- **115行目**: 乗算して返却

#### Step 4: GetByte/SetByteを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Buffer.cls | `Source/CorLib/System/Buffer.cls` | GetByte、SetByteメソッドの実装 |

**主要処理フロー**:
- **125-145行目**: GetByteメソッド - ポインタ演算によるバイト読み取り
- **150-170行目**: SetByteメソッド - ポインタ演算によるバイト書き込み

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

```
Buffer (静的クラス)
    │
    ├─ BlockCopy(Src, SrcOffset, Dst, DstOffset, Count)
    │      ├─ ValidatePrimitiveArray(Src)
    │      ├─ ValidatePrimitiveArray(Dst)
    │      ├─ ValidateRange(Src, SrcOffset, Count)
    │      ├─ ValidateRange(Dst, DstOffset, Count)
    │      └─ CopyMemory(DstPtr + DstOffset, SrcPtr + SrcOffset, Count)
    │
    ├─ ByteLength(Arr)
    │      ├─ ValidatePrimitiveArray(Arr)
    │      └─ ElementCount × ElementSize
    │
    ├─ GetByte(Arr, Index)
    │      ├─ ValidatePrimitiveArray(Arr)
    │      ├─ ValidateIndex(Arr, Index)
    │      └─ ReadByte(ArrPtr + Index)
    │
    └─ SetByte(Arr, Index, Value)
           ├─ ValidatePrimitiveArray(Arr)
           ├─ ValidateIndex(Arr, Index)
           └─ WriteByte(ArrPtr + Index, Value)
```

### データフロー図

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

Src配列 + Dst配列 ─────▶ BlockCopy ───────────────▶ Dst配列（更新）
SrcOffset, DstOffset        │
Count                       ▼
                    CopyMemory API

配列 ──────────────────▶ ByteLength ──────────────▶ バイト長(Long)
                            │
                            ▼
                    要素数 × サイズ

配列 + Index ──────────▶ GetByte ─────────────────▶ バイト値(Byte)
                            │
                            ▼
                    ポインタ読み取り

配列 + Index + Value ──▶ SetByte ─────────────────▶ 配列（更新）
                            │
                            ▼
                    ポインタ書き込み
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Buffer.cls | `Source/CorLib/System/Buffer.cls` | ソース | メインクラス定義 |
| BufferTests.cls | `Source/Tests/System/BufferTests.cls` | テスト | 単体テストケース |
| Statics.bas | `Source/CorLib/Statics.bas` | ソース | 静的クラスのグローバル変数定義 |
| MemoryMethods.bas | `Source/CorLib/MemoryMethods.bas` | ソース | CopyMemory等のAPI宣言 |
