1

現在、ブリザードの .mpq ファイルの 1 つを読み取り用に解凍しています。アンパックされた char バッファーにアクセスするために、boost::interprocess::stream::memorybuffer を使用しています。.mpq ファイルは、常にバージョン ヘッダー (通常は 12 バイト、http: //wiki.devklog.net/index.php?title=The_MoPaQ_Archive_Format#2.2_Archive_Header を参照) で始まるチャンク構造を持っているため、char* 配列表現は切り詰められているようです。ファイルサイズ (約 1.6 MB) が一定のままであり、(おそらく) 常に割り当てられている場合でも、最初の \0 で。結果は、有効長 4 のストリーム バッファです ('REVM' およびバイト番号 5 は \0)。さらに読み取ろうとすると、例外がスローされます。ここに例があります:

    // (somewhere in the code)
{
    MPQFile curAdt(FilePath);    
    size_t size = curAdt.getSize(); // roughly 1.6 mb
    bufferstream memorybuf((char*)curAdt.getBuffer(), curAdt.getSize());
    // bufferstream.m_buf.m_buffer is now 'REVM\0' (Debugger says so), 
    // but internal length field still at 1.6 mb
}
//////////////////////////////////////////////////////////////////////////////

// wrapper around a file oof the mpq_archive of libmpq
MPQFile::MPQFile(const char* filename)    // I apologize my naming inconsistent convention :P
{
    for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i)
    {
        // gOpenArchives points to MPQArchive, wrapper around the mpq_archive, has mpq_archive * mpq_a as member
        mpq_archive &mpq_a = (*i)->mpq_a; 

        // if file exists in that archive, tested via hash table in file, not important here, scroll down if you want

        mpq_hash hash = (*i)->GetHashEntry(filename);
        uint32 blockindex = hash.blockindex;

        if ((blockindex == 0xFFFFFFFF) || (blockindex == 0)) {
            continue; //file not found
        }

        uint32 fileno = blockindex;

        // Found!
        size = libmpq_file_info(&mpq_a, LIBMPQ_FILE_UNCOMPRESSED_SIZE, fileno);
        // HACK: in patch.mpq some files don't want to open and give 1 for filesize
        if (size<=1) {
            eof = true;
            buffer = 0;
            return;
        }
        buffer = new char[size];  // note: size is 1.6 mb at this time

        // Now here comes the tricky part... if I step over the libmpq_file_getdata
        // function, I'll get my truncated char array, which I absolutely don't want^^
        libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);
        return;
    }
}

誰かが私を助けてくれるかもしれません。私はSTLとブーストプログラミングに本当に慣れておらず、とにかくC++プログラミングの経験もありません:P便利な答えを得たいと思っています(plzはlibmpqと基礎となるzlibアーキテクチャを書き直すことを提案しません^^)。MPQFile クラスとその下にある uncompress メソッドは、作業中のプロジェクトから実際に取得されているため、間違いは、streambuffer クラスでのバッファーの使用のどこかにあるか、または私が手掛かりを持っていない char 配列演算の内部の何かのいずれかです。ところで、signed/unsigned char をデータ バッファとして使用する場合の違いは何ですか? 私の問題と何か関係がありますか (コードでは、ランダムに char* unsigned char* が関数の引数として使用されていることがわかります) さらに情報が必要な場合は、お気軽にお問い合わせください:)

4

2 に答える 2

1

あなたがそれを呼ぶとき、あなたはあなたのchar *配列が「切り捨てられている」とどのように判断していますか?印刷またはデバッガーで表示している場合は、\ 0で終了する文字列のように扱われるため、切り捨てられたように見えます。ただし、「バッファ」内のデータには(li​​bmpq_file_getdata()が想定どおりの処理を実行すると仮定して)、ファイル全体またはデータチャンクなどが含まれます。

于 2010-01-12T15:33:16.543 に答える
0

申し訳ありませんが、これらの用語を少し混乱させました(実際にはメモリバッファではなく、ストリームバッファはコードのように意味されています)

ええ、あなたは正しいです...例外処理に誤りがありました。最初のコードの直後に、次のコードが続きます。

// check if the file has been open
//if (!mpf.is_open())
        pair<char*, size_t> temp = memorybuf.buffer();
        if(temp.first)
            throw AdtException(ADT_PARSEERR_EFILE);//Can't open the File

行方不明に注意してください!temp.first の前に。スローされた例外に驚き、ストリームバッファを見て、内部バッファの長さが混乱していました(C#の背景:P)。申し訳ありませんが、現在は期待どおりに機能しています。

于 2010-01-12T16:01:28.250 に答える