2012-01-08 9 views
1

シリアル化されたオブジェクトをストアドファイルから読み戻す際に問題が発生します。 (下記のコードを参照してください)。C++:カスタムオブジェクトのシリアル化/デシリアライゼーションに失敗する

シリアル化プロセスは「うまくいきませんが」と書いてありますが、ユーザーがstd :: ios :: binaryフラグを渡しているかどうかを知る方法がないため、フォーマットしないようにしました。 whitespaceで出力します。

私の最初の試みはサンプルと同じように見えたが、はビット充填の目的でunsigned charであった。下半分と上半分をcharに分割して再構築します。

現在のところ、すべてのデータをファイルに読み込むことができますが、最初の非チェックサムデータを読み込もうとすると、0(charでの試行の場合)またはゴミint sの試み)

シリアライズ:

std::ostream& operator<<(std::ostream& os, const Sprite& data) { 
    int dF = data._dimensions.first; 
    int dS = data._dimensions.second; 

    int cF = data._center.first; 
    int cS = data._center.second; 

    int fF = data._frameDimensions.first; 
    int fS = data._frameDimensions.second; 

    double sF = data._scaleDimensions.first; 
    double sS = data._scaleDimensions.second; 


    std::string name(*data._file); 
    name.shrink_to_fit(); 
    os << 'S' << 'P' << 'R' << (name.length() + 1) << name.c_str() << dF << dS << cF << cS << fF << fS << sF << sS; 
    for(int x = 0; x < data._dimensions.first; ++x) { 
     for(int y = 0; y < data._dimensions.second; ++y) { 
      int color = getpixel(data._image, x, y); 
      os << static_cast<unsigned char>(getr(color)) << static_cast<unsigned char>(getg(color)) << static_cast<unsigned char>(getb(color)); 
     } 
    } 
    int tint = data._tint; 
    os << static_cast<unsigned char>(getr(tint)) << static_cast<unsigned char>(getg(tint)) << static_cast<unsigned char>(getb(tint)); 
    os << data._tintIntensity << data._alpha; 
    return os; 
} 

デシリアライズ:

std::istream& operator>>(std::istream& is, Sprite& data) { 
    char checksum[3]; 
    is >> checksum[0] >> checksum[1] >> checksum[2]; 
    if(checksum[0] != 'S' || checksum[1] != 'P' || checksum[2] != 'R') { 
     is.setstate(std::ios::failbit); 
     return is; 
    } 
    int name_length; 
    is >> name_length; 

    std::string name(name_length, '\0'); 

    for(int i = 0; i <= name_length; ++i) { 
     char current_char = '\0'; 
     is >> current_char; 
     name[i] = current_char; 
    } 

    int upper = 0; 
    int lower = 0; 
    is >> upper; 
    is >> lower; 
    data._dimensions.first = (upper << 8) | lower; 

    upper = 0; 
    lower = 0; 
    is >> upper >> lower; 
    data._dimensions.second = ((upper << 8) | lower); 

    upper = 0; 
    lower = 0; 
    is >> upper >> lower; 
    data._center.first = ((upper << 8) | lower); 

    upper = 0; 
    lower = 0; 
    is >> upper >> lower; 
    data._center.second = ((upper << 8) | lower); 

    upper = 0; 
    lower = 0; 
    is >> upper >> lower; 
    data._frameDimensions.first = ((upper << 8) | lower); 

    upper = 0; 
    lower = 0; 
    is >> upper >> lower; 
    data._frameDimensions.second = ((upper << 8) | lower); 

    double f = 0.0; 
    double s = 0.0; 
    is >> f >> s; 
    data._scaleDimensions.first = f; 
    data._scaleDimensions.second = s; 

    destroy_bitmap(data._image); 
    data._image = NULL; 
    data._image = create_bitmap(data._dimensions.first, data._dimensions.second); 
    for(int x = 0; x < data._dimensions.first; ++x) { 
     for(int y = 0; y < data._dimensions.second; ++y) { 
      unsigned char r = 0; 
      unsigned char g = 0; 
      unsigned char b = 0; 
      is >> r >> g >> b; 
      int color = ((r << 16) | (g << 8) | b); //0xRRGGBB 
      putpixel(data._image, x, y, color); 
     } 
    } 
    unsigned char rtint = 0; 
    unsigned char gtint = 0; 
    unsigned char btint = 0; 
    is >> rtint >> gtint >> btint; 
    data._tint = ((rtint << 16) | (gtint << 8) | btint); //0xRRGGBB 

    is >> data._tintIntensity; 
    is >> data._alpha; 
    return is; 
} 
+1

フォーマットフラグを持って何 'のstd :: ios_base :: binary'フォーマットされたI/Oを行っていないとやって?このフラグは、行末シーケンスの処理方法を決定するだけです。非バイナリモードで '\ n 'を書き込む場合、バイナリモードでは置き換えられません(CR/LFなど)。同様に、行の終わりを読むとき、シーケンスは非バイナリモードでは単一の '\ n'に置き換えられ、バイナリモードではそのまま保持されます。このフラグの有無にかかわらずユーザーが開くのを防ぐには、実際にはフォーマットされたI/Oを使用する必要があります。 –

+0

コードを見る:間にスペースを入れずに複数の値を書き込むと、 'std :: istream'は小さな複数の値ではなく大きな値を読み込みます。おそらく大きな値は、ストリームを悪い状態にするオーバーフローエラーを引き起こすでしょう。これはあなたの問題が始まるところです... –

+0

@DietmarKühl:答えよりも私はそれを受け入れるでしょう。 :D – Casey

答えて

0

はdeserialべきではありません私はbitfiledsを使用する

int upper = 0; 
int lower = 0; 
is >> upper; 
is >> lower; 
data._dimensions.first = upper; 
data._dimensions.second = lower; 

とセンターの類似した、とframeDimensions

-1

:化はこのようなものになります。前に#pragma pack(1)と後に#pragma pack()を追加することを忘れないでください。コンピュータはバイトをアドレス指定できるだけなので、ビットフィールドが8の倍数であることを確認する必要があります。また、ビットのパッキングはコンパイラ/マシンに依存するため、読者は同じコンパイラでコンパイルする必要があります。 は、それからちょうど例えば使用:

somefilestream.write(&some_bitfield_struct, sizeof(some_bitfield_struct)); 
関連する問題