ホーム > デベロッパ > SophiaFramework > BREW C++ 逆引きコード集

BREW C++ プログラミング 逆引きコード集 : ストリーム

C++ で作成されたBREW アプリで、ストリームを扱う方法です。
SophiaFramework を用いています。

gzip による Deflate 圧縮データを解凍する

SFXZIPDecoder クラスを利用して、ストレージ クラスや SFBSourceSFBAStream に格納された gzip による Deflate 圧縮データを解凍します。

// コールバックを使うため、SFXZIPDecoder のインスタンスはクラスのメンバ変数にする
class MyClass {
private:
    SFXFile _file;                      // ファイル クラス のインスタンス
    SFXZIPDecoder _decoder;             // SFXZIPDecoder クラスのインスタンス
    SFXAnsiStringStreamReader  _reader; // 読み込み用ストリーム
    SFXAnsiString _unzipString;         // 解凍後の文字列
public:
    Void Start(Void);

    // コールバック関数
    CALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch)
};

Void MyClass::Start(Void)
{
    SFCError error; // エラー

    // 読み書きモードでファイルを開く
    if ((error = _file.OpenReadOnly(SFXPath("/testdata.tar.gz")))
        == SFERR_NO_ERROR) {

        // ストレージ ( ファイル ) をデコーダに登録する
        if ((error = _decoder.Open(_file)) == SFERR_NO_ERROR) {

            // デコーダから読み込み用ストリームを取得する
            if ((error = _decoder.GetStreamReader(&_reader))
                == SFERR_NO_ERROR) {

                // フェッチする
                if ((error = _reader.Fetch(CALLBACK_FUNCTION(OnFetch)))
                    != SFERR_NO_ERROR) {
                    // エラーのとき
                    _reader.Release();
                }
            }
            if (error != SFERR_NO_ERROR) { 
                // エラーのとき
                _decoder.Close();
            }
        }
        if (error != SFERR_NO_ERROR) { 
            // エラーのとき
            _file.Close();
        }
    }
}

// フェッチが完了したときに呼び出されるコールバック関数
CALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error)
{
    if (error == SFERR_NO_ERROR) {  
        // エラーが発生していないとき

        // 解凍したデータを _unzipString 変数に読み込む
        if ((error = _reader.ReadSFXAnsiString(&_unzipString)) == SFERR_NO_ERROR) {

            // 文字列を表示する
            TRACE("%s", _unzipString.GetCString());
        }
    }
    // 終了処理
    _decoder.Close();
    _file.Close();
}
      

ISource インターフェースからデータを読み込む

SFXSource クラスを利用して、ISource インターフェースからデータを読み込みます。

SFXSource source; 
static ACharConst data[] = "test data"; // 読み込むデータ
SFXAnsiString string;           // 書き込むデータ
SFXBinaryStreamReader reader;   // メモリ読み込み用ストリーム
SFBSourceUtilSmp util;
SFBSourceSmp bs;

// メモリブロックから SFBSource を作成する
util = SFBSourceUtil::NewInstance();
util->SourceFromMemory(data, sizeof(data), null, null, &bs);

// ストレージを開く
if (source.Open(bs) == SFERR_NO_ERROR) {

    // メモリ読み込み用ストリームを取得する
     if (source.GetStreamReader(1024, &reader) == SFERR_NO_ERROR) {

        reader.Fetch();  // フェッチする ( データを読み込む ) 
        reader >> string; // ストリームにデータを読み込む

        // 文字数を取得する size = 9
        TRACE("size = %d", string.GetLength());   
        // 内部バッファを取得する read = test data   
        TRACE("read = %s", string.GetCString());  

        reader.Release();  // ストリームを解放する
    }
    source.Close();  // メモリ ストレージを閉じる
}
      

内部バッファで読み書きを行う

SFXMemory クラスを利用して、内部バッファを読み書きします。

SFXMemory memory;
SFXBinaryStreamWriter writer;   // メモリ書き込み用ストリーム 
SFXBinaryStreamReader reader;   // メモリ読み込み用ストリーム
SFXAnsiString string;           // 書き込むデータ

// メモリ ストレージを開く
if (memory.Open() == SFERR_NO_ERROR) {

    // メモリ書き込み用ストリームを取得する
    if (memory.GetStreamWriter(1024, &writer)== SFERR_NO_ERROR) {

        writer << "abc";  // ストリームにデータを書き込む
        writer.Flush();   // フラッシュする(実際にデータを書き込む)

        // バッファ サイズを取得する size = 4
        TRACE("size = %d", memory.GetSize());    
        // 内部バッファへのポインターを取得する write = abc + '\0'
        TRACE("wrire = %s", memory.GetBuffer()); 
        
        writer.Release();  // ストリームを解放する
    }

    // 先頭へシークする
    memory.SeekStart(0);

    // メモリ読み込み用ストリームを取得する
    if (memory.GetStreamReader(1024, &reader) == SFERR_NO_ERROR) {

        reader.Fetch();  // フェッチする ( データを読み込む ) 
        reader >> string; // ストリームにデータを読み込む

        // 文字数を取得する size = 3
        TRACE("size = %d", string.GetLength());   
        // 内部バッファを取得する read = abc
        TRACE("read = %s", string.GetCString());  

        reader.Release();  // ストリームを解放する
    }
    memory.Close();  // メモリ ストレージを閉じる
}
      

ANSI 文字列のストリームから WIDE 文字列を作成する

ANSI 文字列のストリームから WIDE 文字列を効率よく作成する例

UInt32 length;
SFXBinaryStreamReader stream;
SFXBuffer buffer;
SFXAnsiString ansi;
SFXWideString wide;
SFCError error(SFERR_NO_ERROR);

length = 10; // for test

// ストリームから読み込むためのバッファを確保する
// 文字列クラスへのバッファの委譲では、最後の文字にあたる
// バッファはヌル文字で上書きされる
//  +1 が必要
if ((error = buffer.SetSize(length + 1)) == SFERR_NO_ERROR) {

    // ストリームから ANSI 文字列を読み込む
    if ((error = stream.Read(buffer.GetBuffer(), length)) == SFERR_NO_ERROR) {

        // 最後の文字をヌル終端する
        buffer[length] = '\0';

        // ansi 変数にバッファを委譲する
        if ((error = ansi.AttachSFXBuffer(&buffer)) == SFERR_NO_ERROR) {

            // ANSI 文字列から WIDE 文字列へ変換する
            if ((error = wide.Set(ansi)) == SFERR_NO_ERROR) {

                // wide 変数は有効
                // この例ではバッファのコピーは2回
            }
        }
    }
}
      

ファイルの終端を検知する

バージョン 4.0 以降

ファイルからデータを読み取るストリームでファイルの終端を検知するには、
SFXStreamReader::Ends 関数を使用します。

以下のコードは、ファイルから終端に達するまで1文字ずつ読み込み、表示します。

SFXFile file;
SFXBinaryStreamReader reader;

if (file.OpenReadOnly(SFXPath("/data.txt")) == SFERR_NO_ERROR) {
    // ファイルのオープンに成功したなら
    UInt08 c;
    file.GetStreamReader(10, &reader);

    while (!reader.Ends()) { // ファイルの終端に到達するまで
        if (reader.GetReadableSize() == 0) {
            reader.Fetch();
        }
        reader >> c;      // 1文字読み込み
        TRACE("%c", c);   // 表示
    }
    file.Close();
}

バージョン 3.0

ファイルストリームでファイルの終端を検知するには、
SFUFileStream::IsEOS 関数を使用します。

以下のコードは、ファイルから終端に達するまで1文字ずつ読み込み、表示します。

SFUFileStream fstream;

if (fstream.Open("/data.txt", _OFM_READ) == SFERR_NO_ERROR) {
    // ファイルのオープンに成功したなら
    AChar c;

    while (!fstream.IsEOS()) { // ファイルの終端に到達するまで
        fstream >> c;      // 1文字読み込み
        TRACE("%c", c);    // 表示
    }
    fstream.Close();
}

参照 SFXFile::OpenReadOnly | SFXFile::GetStreamReader |
SFXStreamReader::GetReadableSize | SFXStreamReader::Fetch

      

ファイルから読み込みを行う

バージョン 4.0 以降

ファイルから読み込みを行うには、ファイルクラスから入力ストリームを
取得し、ストリームから読み込みを行います。

SFXFile file;
SFXAnsiStringStreamReader reader;
SFXAnsiString temp;
SFXAnsiString string;   // 読み出した文字列を格納
SFXPath path("/data.txt");  // ファイル名

// ファイルオープン
if (file.OpenReadOnly(path) == SFERR_NO_ERROR) {
    // ファイルオープンに成功した
    
    // 入力ストリームの取得
    file.GetStreamReader(1024, &reader);
    while (!reader.Ends()) { // ファイルの終端まで
        if (reader.GetReadableSize() == 0) {
            reader.Fetch();
        }
        reader >> temp; // ファイルからデータを読み出す
        string += temp;
    }
    file.Close();
}

バージョン 3.0

ファイルから読み込みを行うには、ファイルストリームクラス SFUFileStream
使用します。

SFUFileStream fstream;
SFXAnsiString string;   // 読み出した文字列を格納
SFXAnsiString filename("/data.txt");

// ファイルオープン
if (fstream.Open(filename, _OFM_READ) == SFERR_NO_ERROR) {
    // ファイルオープンに成功した
    fstream >> string; // ファイルから全データを読み出す
    fstream.Close();
}

参照 SFXFile::OpenReadOnly | SFXFile::GetStreamReader |
SFXStreamReader::GetReadableSize | SFXStreamReader::Fetch

      

ファイルに書き込みを行う

バージョン 4.0 以降

ファイルから書き込みを行うには、ファイルクラスから出力ストリームを
取得し、ストリームに書き込みを行います。

SFXFile file;
SFXAnsiStringStreamWriter writer;
SFXAnsiString string("abcdefg"); // 書き込む文字列
SFXPath path("/data.txt"); // ファイル名

// ファイルオープン
if (file.OpenReadWrite(path) == SFERR_NO_ERROR) {
    // ファイルオープンに成功した
    
    // 出力ストリームの取得
    file.GetStreamWriter(string.GetLength(), &writer);
    writer << string;
    writer.Flush();
    file.Close();
}

バージョン 3.0

ファイルに書き込みを行うには、ファイルストリームクラス SFUFileStream
使用します。

SFUFileStream fstream;
SFXAnsiString string("abcdefg");      // 書き込む文字列
SFXAnsiString filename("/data.txt");     // ファイル名

//ファイル新規作成
if (fstream.Open(filename, _OFM_CREATE) == SFERR_NO_ERROR) {
    // 新規作成に成功したなら
    fstream << string;                 // ファイルに書き込み
    fstream.Close();
}

参照 SFXFile::OpenReadWrite | SFXFile::GetStreamWriter |
SFXStreamWirter::Flush