目次 - 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ストリームを閉じるコールバック関数 (詳細を参照すること)
Uint32typeストリームの種類 (詳細を参照すること)
unionhidden種類に固有のデータ (詳細を参照すること)

サンプルコード

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_SET0データの先頭からシークする
RW_SEEK_CUR1現在の読込位置からシークする
RW_SEEK_END2データの末尾からシークする

読込関数

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

書込関数

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

閉じる関数

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

ストリームの種類

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

識別子機能
SDL_RWOPS_UNKNOWN0不明またはアプリケーション定義のストリーム
SDL_RWOPS_WINFILE1win32 ファイルハンドラ
SDL_RWOPS_STDFILE2stdio.h FILE*
SDL_RWOPS_JNIFILE3Androidの資源
SDL_RWOPS_MEMORY4メモリストリーム(読込/書込)
SDL_RWOPS_MEMORY_RO5メモリストリーム(読込専用)

アプリケーションとライブラリ独自の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