# 機能設計書: System.IO.Pipes（パイプ通信）

## 1. 機能概要

### 1.1 機能名
System.IO.Pipes（パイプ通信）

### 1.2 機能ID
FUNC-019

### 1.3 機能説明
.NET ランタイムにおけるプロセス間通信（IPC）機能を提供するライブラリ。名前付きパイプと匿名パイプの両方をサポートし、同一マシン上のプロセス間でのデータ交換を可能にする。Streamベースのバイトストリームおよびメッセージモードでの通信をサポートする。

### 1.4 関連画面
- なし（基盤ライブラリのため直接的な関連画面は存在しない）

## 2. 機能要件

### 2.1 入力仕様

| 項目名 | データ型 | 必須 | 説明 |
|--------|----------|------|------|
| pipeName | string | Yes | パイプ名（名前付きパイプ） |
| serverName | string | No | サーバー名（デフォルト: "."） |
| direction | PipeDirection | Yes | パイプの方向 |
| transmissionMode | PipeTransmissionMode | No | 転送モード |
| options | PipeOptions | No | パイプオプション |
| buffer | byte[] | Yes | 送受信バッファ |

### 2.2 出力仕様

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| int | int | 読み書きバイト数 |
| bool | bool | 接続状態 |
| SafePipeHandle | SafePipeHandle | パイプハンドル |

### 2.3 処理フロー（名前付きパイプサーバー）

```
NamedPipeServerStream(pipeName)
    │
    ▼
┌─────────────────────┐
│ WaitForConnectionAsync│
│ 接続待ち            │
└─────────────────────┘
    │ クライアント接続
    ▼
┌─────────────────────┐
│ State: Connected    │
│ 読み書き可能        │
└─────────────────────┘
    │
    ├── ReadAsync()
    ├── WriteAsync()
    │
    ▼
┌─────────────────────┐
│ Disconnect()       │
│ 切断・再利用可能    │
└─────────────────────┘
```

## 3. 詳細設計

### 3.1 クラス構成

#### 3.1.1 主要クラス

| クラス名 | 責務 |
|----------|------|
| PipeStream | パイプストリームの抽象基底クラス |
| NamedPipeServerStream | 名前付きパイプサーバー |
| NamedPipeClientStream | 名前付きパイプクライアント |
| AnonymousPipeServerStream | 匿名パイプサーバー |
| AnonymousPipeClientStream | 匿名パイプクライアント |
| SafePipeHandle | パイプハンドルの安全なラッパー |

### 3.2 PipeStream クラス（PipeStream.cs）

#### 3.2.1 フィールドとプロパティ

```csharp
// PipeStream.cs: 15-29行目
internal const string AnonymousPipeName = "anonymous";

private SafePipeHandle? _handle;
private bool _canRead;
private bool _canWrite;
private bool _isAsync;
private bool _isCurrentUserOnly;
private bool _isMessageComplete;
private bool _isFromExistingHandle;
private bool _isHandleExposed;
private PipeTransmissionMode _readMode;
private PipeTransmissionMode _transmissionMode;
private PipeDirection _pipeDirection;
private uint _outBufferSize;
private PipeState _state;
```

#### 3.2.2 コンストラクタ

```csharp
// PipeStream.cs: 31-40行目
protected PipeStream(PipeDirection direction, int bufferSize)
{
    if (direction < PipeDirection.In || direction > PipeDirection.InOut)
    {
        throw new ArgumentOutOfRangeException(nameof(direction), SR.ArgumentOutOfRange_DirectionModeInOutOrInOut);
    }
    ArgumentOutOfRangeException.ThrowIfNegative(bufferSize);

    Init(direction, PipeTransmissionMode.Byte, (uint)bufferSize);
}

// PipeStream.cs: 42-55行目
protected PipeStream(PipeDirection direction, PipeTransmissionMode transmissionMode, int outBufferSize)
{
    // バリデーション
    Init(direction, transmissionMode, (uint)outBufferSize);
}
```

#### 3.2.3 初期化メソッド

```csharp
// PipeStream.cs: 57-84行目
private void Init(PipeDirection direction, PipeTransmissionMode transmissionMode, uint outBufferSize)
{
    _readMode = transmissionMode;
    _transmissionMode = transmissionMode;
    _pipeDirection = direction;

    if ((_pipeDirection & PipeDirection.In) != 0)
    {
        _canRead = true;
    }
    if ((_pipeDirection & PipeDirection.Out) != 0)
    {
        _canWrite = true;
    }

    _outBufferSize = outBufferSize;
    _isMessageComplete = true;
    _state = PipeState.WaitingToConnect;
}
```

#### 3.2.4 ハンドル初期化

```csharp
// PipeStream.cs: 89-102行目
protected void InitializeHandle(SafePipeHandle? handle, bool isExposed, bool isAsync)
{
    if (isAsync && handle != null)
    {
        InitializeAsyncHandle(handle);
    }

    _handle = handle;
    _isAsync = isAsync;
    _isHandleExposed = isExposed;
    _isFromExistingHandle = isExposed;
}
```

#### 3.2.5 読み書きメソッド

```csharp
// PipeStream.cs: 113-122行目
public override int ReadByte()
{
    byte b = 0;
    return Read(new Span<byte>(ref b)) > 0 ? b : -1;
}

public override void WriteByte(byte value)
{
    Write([value]);
}

public override void Flush()
{
    CheckWriteOperations();
    // パイプではFlushは何もしない（デッドロック防止）
}
```

### 3.3 接続状態管理

#### 3.3.1 IsConnectedプロパティ

```csharp
// PipeStream.cs: 174-184行目
public bool IsConnected
{
    get
    {
        return State == PipeState.Connected;
    }
    protected set
    {
        _state = (value) ? PipeState.Connected : PipeState.Disconnected;
    }
}
```

#### 3.3.2 IsMessageCompleteプロパティ

```csharp
// PipeStream.cs: 193-224行目
public bool IsMessageComplete
{
    get
    {
        if (_state == PipeState.WaitingToConnect)
        {
            throw new InvalidOperationException(SR.InvalidOperation_PipeNotYetConnected);
        }
        if (_state == PipeState.Disconnected)
        {
            throw new InvalidOperationException(SR.InvalidOperation_PipeDisconnected);
        }
        // ... 他の検証
        if (_readMode != PipeTransmissionMode.Message)
        {
            throw new InvalidOperationException(SR.InvalidOperation_PipeReadModeNotMessage);
        }

        return _isMessageComplete;
    }
}
```

### 3.4 操作チェックメソッド

```csharp
// PipeStream.cs: 323-335行目
protected internal virtual void CheckPipePropertyOperations()
{
    if (CheckOperationsRequiresSetHandle && _handle == null)
    {
        throw new InvalidOperationException(SR.InvalidOperation_PipeHandleNotSet);
    }
    if ((_state == PipeState.Closed) || (_handle != null && _handle.IsClosed))
    {
        throw Error.GetPipeNotOpen();
    }
}

// PipeStream.cs: 339-360行目
protected internal void CheckReadOperations()
{
    if (_state == PipeState.WaitingToConnect)
    {
        throw new InvalidOperationException(SR.InvalidOperation_PipeNotYetConnected);
    }
    if (_state == PipeState.Disconnected)
    {
        throw new InvalidOperationException(SR.InvalidOperation_PipeDisconnected);
    }
    // ... 追加チェック
}

// PipeStream.cs: 363-390行目
protected internal void CheckWriteOperations()
{
    // 読み取りと同様のチェック + Broken状態チェック
    if (_state == PipeState.Broken)
    {
        throw new IOException(SR.IO_PipeBroken);
    }
}
```

### 3.5 PipeDirection 列挙型

| 方向 | 値 | 説明 |
|------|-----|------|
| In | 1 | 入力（読み取り）のみ |
| Out | 2 | 出力（書き込み）のみ |
| InOut | 3 | 双方向 |

### 3.6 PipeTransmissionMode 列挙型

| モード | 値 | 説明 |
|--------|-----|------|
| Byte | 0 | バイトストリームモード |
| Message | 1 | メッセージモード |

### 3.7 PipeState 列挙型

| 状態 | 説明 |
|------|------|
| WaitingToConnect | 接続待ち |
| Connected | 接続済み |
| Disconnected | 切断済み |
| Broken | 破損（相手が予期せず切断） |
| Closed | クローズ済み |

### 3.8 NamedPipeServerStream

#### 3.8.1 コンストラクタ

```csharp
public NamedPipeServerStream(string pipeName);
public NamedPipeServerStream(string pipeName, PipeDirection direction);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances,
    PipeTransmissionMode transmissionMode);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances,
    PipeTransmissionMode transmissionMode, PipeOptions options);
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances,
    PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize);
```

#### 3.8.2 接続メソッド

```csharp
public void WaitForConnection();
public Task WaitForConnectionAsync();
public Task WaitForConnectionAsync(CancellationToken cancellationToken);
public void Disconnect();
```

### 3.9 NamedPipeClientStream

#### 3.9.1 コンストラクタ

```csharp
public NamedPipeClientStream(string pipeName);
public NamedPipeClientStream(string serverName, string pipeName);
public NamedPipeClientStream(string serverName, string pipeName, PipeDirection direction);
public NamedPipeClientStream(string serverName, string pipeName, PipeDirection direction,
    PipeOptions options);
public NamedPipeClientStream(string serverName, string pipeName, PipeDirection direction,
    PipeOptions options, TokenImpersonationLevel impersonationLevel);
```

#### 3.9.2 接続メソッド

```csharp
public void Connect();
public void Connect(int timeout);
public Task ConnectAsync();
public Task ConnectAsync(int timeout);
public Task ConnectAsync(CancellationToken cancellationToken);
public Task ConnectAsync(int timeout, CancellationToken cancellationToken);
```

## 4. エラー処理

### 4.1 例外一覧

| 例外 | 発生条件 |
|------|----------|
| InvalidOperationException | 不正な状態での操作 |
| IOException | パイプ破損、I/Oエラー |
| ObjectDisposedException | Dispose後の操作 |
| TimeoutException | 接続タイムアウト |
| UnauthorizedAccessException | アクセス権限がない |
| ArgumentException | 引数が不正 |

### 4.2 状態遷移と例外

| 現在の状態 | 操作 | 結果 |
|------------|------|------|
| WaitingToConnect | Read/Write | InvalidOperationException |
| Disconnected | Read/Write | InvalidOperationException |
| Broken | Write | IOException |
| Closed | Any | ObjectDisposedException |

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

### 5.1 アクセス制御
- PipeSecurity によるアクセス制御（Windows）
- CurrentUserOnly オプションによる制限

### 5.2 偽装
- TokenImpersonationLevel による偽装制御（クライアント側）
- GetImpersonationUserName() による確認（サーバー側）

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

### 6.1 推奨読解順序

1. **データ構造の理解**
   - `PipeDirection.cs`: パイプ方向
   - `PipeTransmissionMode.cs`: 転送モード
   - `PipeOptions.cs`: オプション
   - `PipeState.cs`: 状態列挙

2. **エントリーポイント**
   - `PipeStream.cs`: 抽象基底クラス
   - **15-29行目**: フィールド定義
   - **31-55行目**: コンストラクタ
   - **57-84行目**: Init メソッド
   - **174-184行目**: IsConnected
   - **323-390行目**: 操作チェックメソッド

3. **具体実装**
   - `NamedPipeServerStream.cs`: サーバー実装
   - `NamedPipeClientStream.cs`: クライアント実装
   - `AnonymousPipeServerStream.cs`: 匿名パイプサーバー
   - `AnonymousPipeClientStream.cs`: 匿名パイプクライアント

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

```
new NamedPipeServerStream(pipeName, direction)
    │
    └── PipeStream(direction, bufferSize)
            │
            └── Init(direction, transmissionMode, bufferSize)
                    │
                    ├── _canRead/_canWrite設定
                    └── _state = WaitingToConnect

server.WaitForConnectionAsync()
    │
    ├── CheckConnectOperations()
    │
    └── OS固有待機処理
            │
            └── 接続成功時: IsConnected = true

server.ReadAsync(buffer)
    │
    ├── CheckReadOperations()
    │       │
    │       └── 状態検証
    │
    └── ReadAsyncCore(buffer)
            │
            └── SafePipeHandle.ReadAsync()
```

### 6.3 データフロー図

```
┌──────────────────┐     ┌──────────────────┐
│ クライアント       │     │ サーバー          │
│ NamedPipeClient  │     │ NamedPipeServer  │
└────────┬─────────┘     └────────┬─────────┘
         │                        │
         │ ConnectAsync()         │ WaitForConnectionAsync()
         │                        │
         ├────────────────────────┤
         │     パイプ接続確立      │
         ├────────────────────────┤
         │                        │
         │ WriteAsync(data)       │
         │ ─────────────────────→ │ ReadAsync()
         │                        │
         │                        │ WriteAsync(response)
         │ ReadAsync() ←───────── │
         │                        │
         │ Dispose()              │ Disconnect()
         └────────────────────────┘
```

### 6.4 読解のコツ

#### 6.4.1 PipeState の遷移
```
WaitingToConnect → Connected → Disconnected
                           ↘ Broken
                              ↓
                           Closed
```

#### 6.4.2 部分クラス構成
PipeStream は partial class でプラットフォーム別実装:
- `PipeStream.cs`: 共通ロジック
- `PipeStream.Unix.cs`: Unix 固有
- `PipeStream.Windows.cs`: Windows 固有

#### 6.4.3 Flush の特殊性
パイプでは Flush は何もしない:
```csharp
public override void Flush()
{
    CheckWriteOperations();
    // FlushFileBuffers を呼ぶとデッドロックの可能性
}
```

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

| パス | 種別 | 役割 |
|------|------|------|
| `src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.cs` | ソース | 抽象基底クラス |
| `src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.cs` | ソース | 名前付きパイプサーバー |
| `src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs` | ソース | 名前付きパイプクライアント |
| `src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeServerStream.cs` | ソース | 匿名パイプサーバー |
| `src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeClientStream.cs` | ソース | 匿名パイプクライアント |
| `src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeDirection.cs` | ソース | 方向列挙型 |
| `src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeTransmissionMode.cs` | ソース | 転送モード列挙型 |
| `src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeOptions.cs` | ソース | オプション列挙型 |

## 7. 使用例

### 7.1 名前付きパイプサーバー

```csharp
using var server = new NamedPipeServerStream("testpipe", PipeDirection.InOut);
Console.WriteLine("Waiting for connection...");
await server.WaitForConnectionAsync();

var buffer = new byte[256];
int bytesRead = await server.ReadAsync(buffer);
Console.WriteLine($"Received: {Encoding.UTF8.GetString(buffer, 0, bytesRead)}");

await server.WriteAsync(Encoding.UTF8.GetBytes("Hello from server"));
server.Disconnect();
```

### 7.2 名前付きパイプクライアント

```csharp
using var client = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut);
await client.ConnectAsync(5000);

await client.WriteAsync(Encoding.UTF8.GetBytes("Hello from client"));

var buffer = new byte[256];
int bytesRead = await client.ReadAsync(buffer);
Console.WriteLine($"Received: {Encoding.UTF8.GetString(buffer, 0, bytesRead)}");
```

### 7.3 匿名パイプ（親子プロセス間）

```csharp
// 親プロセス
using var server = new AnonymousPipeServerStream(PipeDirection.Out);
string clientHandle = server.GetClientHandleAsString();

// 子プロセス起動時に clientHandle を渡す
Process.Start("child.exe", clientHandle);

server.DisposeLocalCopyOfClientHandle();
await server.WriteAsync(data);
```

## 8. テスト観点

### 8.1 単体テスト観点
- 接続・切断のライフサイクル
- 各方向（In/Out/InOut）での動作
- バイトモード・メッセージモードの動作
- タイムアウト処理

### 8.2 結合テスト観点
- 複数クライアントとの同時通信
- 大量データ転送
- プロセス間通信の検証

### 8.3 性能テスト観点
- スループット測定
- レイテンシ測定
- 同時接続数の影響

## 9. 変更履歴

| バージョン | 日付 | 変更内容 |
|------------|------|----------|
| 1.0 | 2026-01-30 | 初版作成 |
