前のページ次のページ上に戻るホーム SophiaFramework UNIVERSE 5.3

18.9. サンプルコード

18.9.1. ファイルからメモリへの読み込み

以下は、 SFXFile クラスや SFXMemory クラスを使用してファイルストレージからメモリストレージへデータを読み込むコードです。

例 18.13. ファイルからメモリへの読み込み

class MyClass {
private:
    SFXBuffer _buffer;  // ファイルストレージからメモリストレージへ読み込んだデータを格納するバッファ
public:
    SFCError MyClass::ReadDataFromFileToMemory(Void);
};

SFCError MyClass::ReadDataFromFileToMemory(Void)
{ 
    SFCError error;               // エラー値
    SFXFile file;                 // 入力ファイル
    SFXBinaryStreamReader reader; // ファイル読み込み用ストリーム
    SFXMemory memory;             // メモリストレージ
    SFXBinaryStreamWriter writer; // メモリ書き込み用ストリーム
    UInt08 c;                     // 一時変数

    // ファイルを開く
    if ((error = file.OpenReadOnly(SFXPath("/dir/data.txt"))) == SFERR_NO_ERROR) {

        // ファイル読み込み用ストリームを取得する
        if ((error = file.GetStreamReader(1024, &reader)) == SFERR_NO_ERROR) {

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

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

                    // ファイルからファイル読み込み用ストリームバッファにデータを読み込む
                    if ((error = reader.Fetch()) == SFERR_NO_ERROR) {

                        // ファイルの終端まで繰り返す
                        while ((error == SFERR_NO_ERROR) && !reader.Ends()) {

                            if (reader.GetReadableSize() > 0) {

                                // ファイル読み込み用ストリームバッファにデータがあるとき:

                                // ファイル読み込み用ストリームバッファからデータ(1 バイト)を読み込む
                                reader >> c;

                                if (c != '\r' & c != '\n') { 

                                    // 改行文字でないとき:

                                    // メモリ書き込み用ストリームバッファにデータを書き込む
                                    writer << c;
                                }
                                if (writer.GetWritableSize() == 0) {

                                    // メモリ書き込み用ストリームバッファに空きがないとき:

                                    // メモリ書き込み用ストリームバッファからメモリにデータを書き込む
                                    error = writer.Flush();
                                }
                            }
                            else { 

                                // ファイル読み込み用ストリームバッファにデータがないとき:

                                // ファイルからファイル読み込み用ストリームバッファにデータを読み込む
                                error = reader.Fetch();
                            }
                        }
                        if (error == SFERR_NO_ERROR) {

                            // 終端の '\0' を書き込む
                            writer << static_cast<UInt08>('\0');

                            if ((error = writer.Flush()) == SFERR_NO_ERROR) {

                                // メモリストレージの内容をデバッグウィンドウに表示する
                                TRACE("%s", memory.GetBuffer());
                            }
                        }
                    }
                    // メモリ書き込み用ストリームを解放する
                    writer.Release();
                }
                // メモリストレージの内容をバッファに格納し、メモリストレージを閉じる
                // ※ この場合、エラー値を返すことに注意
                error = memory.Close(&_buffer);
            }
            // ファイル読み込み用ストリームを解放する
            reader.Release();
        }
        // ファイルを閉じる
        file.Close();
    }
    if (error != SFERR_NO_ERROR) {

        TRACE("An error has occurred during processing! Error code: %d", error);
    }
    return error;
}

18.9.2. 画像ダウンロード

以下は、 SFXSource クラスを使用して Web サーバーから画像データを SFBImage インスタンスにダウンロードして画面に描画するコードです。

例 18.14. HTTP 通信でダウンロードした画像を SFBImage インスタンスとして扱う方法

// コールバック関数で使用するので _http や _image はクラスのメンバ変数として定義する
class MyClass {
private:
    SFXHTTPConnection _http;
    SFBImageSmp _image;
public:
    Void Start(Void);
    XALLBACK_DECLARE_SFXHTTPCONNECTION(OnConnect)

    // コールバック関数の実体
    Void OnReadImage(SFCError error);  
    // ダミーのコールバック関数: 静的メンバ関数として定義する
    static Void OnReadImageSHP(VoidPtr reference, IImage *  pIImage, AEEImageInfo * pi, int nErr);  
};

Void MyClass::Start(Void)
{
    SFCError error(SFERR_NO_ERROR);

    // GET メソッドでアクセスする

    // 接続を開く
    if ((error = _http.Open()) == SFERR_NO_ERROR) {

        // 接続を開始する
        // Web サーバーへ接続する
        // ※ 接続要求の結果は、OnConnect 関数に通知される
        if ((error = _http.Connect("http://www.example.com/example.bmp", XALLBACK_INTERNAL(OnConnect))) == SFERR_NO_ERROR) {

            TRACE(">> connecting...");
        }
    }

    if (error != SFERR_NO_ERROR) {

        // エラーが発生したとき
        // 接続を閉じる
        _http.Close();
    }
    return;
}

// HTTP 接続要求の結果が通知されるコールバック関数
XALLBACK_IMPLEMENT_SFXHTTPCONNECTION(MyClass, OnConnect, error)
{
    SFBSourceSmp source;
    SFXSource    temp;

    if (error == SFERR_NO_ERROR) {

        if (_http.GetResultCode() == 200) {

            // HTTP レスポンスボディを管理するソースを取得する
            if ((source = _http.GetResponseContent()) != null) {

                // BMP 形式画像オブジェクトを生成する
                if ((_image = SFBImage::NewInstance(AEECLSID_WINBMP)) == SFERR_NO_ERROR) {

                    // コールバックを設定する
                    // ※画像データ読み込みの結果は、OnReadImageSHP 関数に通知される
                    _image->Notify(OnReadImageSHP, this);

                    // SFXSource にソースを設定する
                    if (temp.Open(source) == SFERR_NO_ERROR) {

                         // ソースから画像データを読み込む
                        if (_image->SetStream(temp) != SFERR_NO_ERROR) {

                            // エラーが発生したとき
                            _http.Close();
                            TRACE("An error occurred during setting the stream!");
                        }
                        // ソースを閉じる
                        temp.Close();
                    } else {
 
                        // エラーが発生したとき
		        _http.Close();
                        TRACE("An error occurred during setting the source storage!");
                    }
                } else { 

                    // エラーが発生したとき
                    TRACE("An error occurred during creating the image object!");
                    _http.Close();
                }
            } else {

               // エラーが発生したとき
               _http.Close();
               TRACE("An error occurred during getting the source storage!");
            }
	} else {

            // エラーが発生したとき
            _http.Close();
            TRACE("The result code is not 200!");
	}
    } else {

        // エラーが発生したとき
        _http.Close();
        TRACE("An error occurred during connecting to the web server!");
    }
    return;
}

// 画像データ読み込みの結果が通知されるダミーのコールバック関数
Void MyClass::OnReadImageSHP(VoidPtr reference, IImage *  pIImage, AEEImageInfo * pi, int nErr)
{
    // 実際のコールバック関数を呼び出す
    static_cast<MyClassPtr>(reference)->OnReadImage(nErr); 
    return;
}

// 実際のコールバック関数
Void MyClass::OnReadImage(SFCError error)
{
    SFXGraphicsPtr graphics(SFXGraphics::GetInstance());
 
    if (error == SFERR_NO_ERROR) {
 
        // 画像オブジェクトを (0, 0) の位置に描画する
        _image->Draw(SFXGrid(0,0));

        // 画面を更新する
        graphics->Update();
    } else {

        // エラーが発生したとき
        TRACE("An error occurred during downloading image data!");
    }
    // 接続を閉じる
    _http.Close();
    return;
}

18.9.3. gzip ファイルの解凍

以下は、 SFXZIPDecoder クラスを使用して ストリーム経由でファイルからメモリ(_unzipString 変数)に gzip 圧縮されたデータを解凍しながら読み込むコードです。

例 18.15. gzip ファイルの解凍

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

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

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

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

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

            // gzip デコーダから読み込み用ストリームを取得する
            // ※ size 引数を指定していないので、ストリームバッファは可変長
            if ((error = _decoder.GetStreamReader(&_reader)) == SFERR_NO_ERROR) {

                // フェッチを行う: 実際に gzip デコーダからからストリームバッファにデータを読み込む
                // ※1. 読み込み(フェッチ)の結果は、OnFetch 関数に通知される
                // ※2. ストリームバッファは、読み込むデータのサイズに合わせて自動的に拡張される
                if ((error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch))) != SFERR_NO_ERROR) {

                    // エラーのとき: OnFetch 関数は呼び出されない

                    _reader.Release();
                }
            }
            if (error != SFERR_NO_ERROR) { 

                // エラーが発生したとき
                _decoder.Close();
            }
        }
        if (error != SFERR_NO_ERROR) { 

            // エラーが発生したとき
            _file.Close();
        }
    }
}

// 読み込み(フェッチ)の結果が通知されるコールバック関数
XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error)
{
    if (error == SFERR_NO_ERROR) {  
        // 読み込み(フェッチ)が成功したとき

        // ストリームバッファから _unzipString 変数にデータを読み込む(データは解凍されている)
        if ((error = _reader.ReadSFXAnsiString(&_unzipString)) == SFERR_NO_ERROR) {

            // _unzipString 変数の内容をデバッグウィンドウに表示する
            TRACE("%s", _unzipString.GetCString());

            _reader.Release();
        }
    }

    // 終了処理
    _decoder.Close();
    _file.Close();
}