目次 - API(機能別) - ファイル入出力 - SDL_RWops

# SDL_RWops

ストリーム入出力の抽象インターフェースを提供する構造体. アプリケーションは通常この構造体の内部を無視し, 不透明ポインタとして扱うことができる. しかし, 入出力を実装する低レベルコードにとっては, その詳細は重要である.

## フィールド

Sint64 (*)(SDL_RWops *) | size | ストリームサイズを報告するコールバック関数 (詳細を参照すること)
Sint64 (*)(SDL_RWops *, Sint64, int) | seek | ストリームをシークするコールバック関数 (詳細を参照すること)
size_t (*)(SDL_RWops *, void *, size_t, size_t) | read | ストリームから読み込むコールバック関数 (詳細を参照すること)
size_t (*)(SDL_RWops *, const void *, size_t, size_t) | write | ストリームに書き込むコールバック関数 (詳細を参照すること)
int (*)(SDL_RWops *) | close | ストリームを閉じるコールバック関数 (詳細を参照すること)
Uint32 | type | ストリームの種類 (詳細を参照すること)
union | hidden | 種類に固有のデータ (詳細を参照すること)

## サンプルコード

``

    SDL_RWops *io = SDL_RWFromFile("username.txt", "rb");
    if (io != NULL) {
        char name[256];
        if (io->read(io, name, sizeof (name), 1) > 0) {
            printf("こんにちは %s!\n", name);
        }
        io->close(io);
    }

次の例の動きは上と同じだが, マクロインターフェースを使っている. この書き方が推奨されている. ``

    SDL_RWops *io = SDL_RWFromFile("username.txt", "rb");
    if (io != NULL) {
        char name[256];
        if (SDL_RWread(io, name, sizeof (name), 1) > 0) {
            printf("こんにちは %s!\n", name);
        }
        SDL_RWclose(io);
    }

## 詳細

SDL_RWopsは入出力を抽象化したものである. ストリームの読み込み, 書き込み, シークが提供されており, 呼び出し側はデータがどこから来たものかを知る必要がない.

例えば, SDL_RWopsがメモリバッファ, ディスク上のファイル, 接続されたwebサーバに設定されていても, 呼び出し側はデータの操作方法を変える必要がない.

SDLはファイルやメモリバッファのようなストリームを読み込むいくつかの内部メソッドを提供している. しかし, この構造体はどのような種類のストリームでもアプリケーションやサードパーティーのライブラリで実装することができる.

この構造体のほとんどのフィールドはストリームインターフェースの実装へのコールバックとして使われる関数へのポインタである. これらの呼び出し規約は全てSDLCALLである.

SDL1.2ではこれらの関数の多くはintを使っていたが, SDL2.0ではより広い範囲を扱うためSint64になっている.

アプリケーションはこの構造体の内部について知る必要はない. 不透明ポインタとして扱い, SDL_RWread(), SDL_RWwrite(), SDL_RWseek(), SDL_RWtell(), SDL_RWclose()関数を使えばよい. また, SDL_RWFromFile()やSDL_RWFromMem()などを使えば, アプリケーションはこの構造体を生成, 修正することもほとんどない.

しかし, サードパーティーライブラリや特別な低レベルコードの場合は, この構造体がどのように実装されているかを知る必要がある.

### サイズ関数

sizeはストリーム全体のバイト数を報告する関数へのポインタである. もし, ストリームのサイズが決められなければ(サイズを知る方法がない, またはエラーが発生した), この関数は-1を戻す.

### シーク関数

seekはストリームの次に読み込む/書き込む位置を設定する関数へのポインタである. シークはバイト単位で設定する. シークできなければ(シークする方法がない, またはエラーが発生した), この関数は-1を戻す. シークできれば新しい位置を戻すRW_SEEK_CURから0byteシークすると現在の位置を得ることができる.

最後の引数は標準のfseek()の"whence"のように働く:

識別子 | 値 | 機能
--- | --- | ---
RW_SEEK_SET | 0 | データの先頭からシークする
RW_SEEK_CUR | 1 | 現在の読込位置からシークする
RW_SEEK_END | 2 | データの末尾からシークする

### 読込関数

readはストリームから読み込み関数へのポインタである. それぞれsizeバイトの最大num個のオブジェクトを読み込みptrポインタへ書き込む. 読み込んだオブジェクトの数を戻す. それは最大要求数以下の場合がある. エラーまたは終端の場合は0を戻す.

### 書込関数

writeはストリームへ書き込む関数へのポインタである. それぞれsizeバイトのnum個のオブジェクトをポインタptrから書き込む. 書き込んだオブジェクトの数を戻す. 要求より少ない場合はエラーである.

### 閉じる関数

closeはストリームを閉じる関数へのポインタである. ストリームで使ったあらゆる資源とSDL_RWops自身をSDL_FreeRW()で解放する必要がある. 成功のとき0, ディスクへの書き込みに失敗したときなどは-1を戻す. 書き込みに失敗した場合でも, この関数を呼んだ後はSDL_RWopsは使えない.

### ストリームの種類

typeフィールドは次の値の1つである. アプリケーションは通常この情報を無視できる.

識別子 | 値 | 機能
--- | --- | ---
SDL_RWOPS_UNKNOWN | 0 | 不明またはアプリケーション定義のストリーム
SDL_RWOPS_WINFILE | 1 | win32 ファイルハンドラ
SDL_RWOPS_STDFILE | 2 | stdio.h FILE*
SDL_RWOPS_JNIFILE | 3 | Androidの資源
SDL_RWOPS_MEMORY | 4 | メモリストリーム(読込/書込)
SDL_RWOPS_MEMORY_RO | 5 | メモリストリーム(読込専用)

アプリケーションとライブラリ独自のSDL_RWopsの実装の場合はSDL_RWOPS_UNKNOWNにする必要がある. 他の値は全てSDLが内部で使うために予約されている.

### 固有のデータ

アプリケーションはこの共用体を完全に無視できる. この共用体の全てのフォールドはSDL内部で使用しており, 1つの例外を除き環境依存かつ参照禁止である. 自分でSDL_RWopsを実装する場合はunknown共用体を使うことができる. その場合閉じるときに消去する必要がある. もし2つのポインタを設定したいならば, このポインタを実際のデータの構造体の領域へのポインタとして使うとよい.

## 関連項目(関数)

SDL_AllocRW
SDL_FreeRW
SDL_RWclose SDL_RWFromConstMem
SDL_RWFromFile
SDL_RWFromFP
SDL_RWFromMem
SDL_RWread
SDL_RWseek
SDL_RWtell
SDL_RWwrite

## SDL Wikiへのリンク

SDL_RWops - SDL Wiki