C++ boost memorybuffer和char数组

C++ boost memorybuffer和char数组,c++,memory,boost,char,truncated,C++,Memory,Boost,Char,Truncated,我目前正在解包暴雪的一个.mpq文件以供阅读。 为了访问未打包的字符缓冲区,我使用了boost::interprocess::stream::memorybuffer。 由于.mpq文件的分块结构总是以版本头开始(通常为12字节,请参阅),因此char*数组表示形式似乎在第一个\0处截断,即使文件大小(大约1.6mb)保持不变并且(可能)总是分配。 结果是一个有效长度为4的streambuffer(“REVM”和字节nr.5为\0)。当尝试进一步读取时,将引发异常。这里有一个例子: //

我目前正在解包暴雪的一个.mpq文件以供阅读。 为了访问未打包的字符缓冲区,我使用了boost::interprocess::stream::memorybuffer。 由于.mpq文件的分块结构总是以版本头开始(通常为12字节,请参阅),因此char*数组表示形式似乎在第一个\0处截断,即使文件大小(大约1.6mb)保持不变并且(可能)总是分配。 结果是一个有效长度为4的streambuffer(“REVM”和字节nr.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;
    }
}
//(代码中的某个地方)
{
MPQFile-curAdt(文件路径);
size_t size=curAdt.getSize();//大约1.6MB
bufferstream memorybuf((char*)curAdt.getBuffer(),curAdt.getSize());
//bufferstream.m_buf.m_buffer现在是'REVM\0'(调试器这么说),
//但内部长度字段仍为1.6MB
}
//////////////////////////////////////////////////////////////////////////////
//包装libmpq的mpq\u归档文件
MPQFile::MPQFile(const char*filename)//很抱歉我的命名不一致约定:P
{
for(ArchiveSet::iterator i=gOpenArchives.begin();i!=gOpenArchives.end();+i)
{
//gOpenArchives指向MPQArchive,它是mpq_归档的包装器,其成员为mpq_归档*mpq_a
mpq_档案&mpq_a=(*i)->mpq_a;
//若该文件存在于该归档文件中,通过该文件中的哈希表进行测试,在这里并不重要,若需要,向下滚动
mpq_hash hash=(*i)->GetHashEntry(文件名);
uint32 blockindex=hash.blockindex;
如果((块索引==0xFFFFFF)| |(块索引==0)){
继续;//找不到文件
}
uint32 fileno=块索引;
//找到了!
大小=libmpq_文件信息(&mpq_a,libmpq_文件未压缩_大小,文件号);
//HACK:在patch.mpq中,有些文件不想打开,文件大小为1

如果(size您如何确定您的char*数组被您称之为“截断”?如果您正在打印它或在调试器中查看它,它将看起来被截断,因为它将被视为字符串,由\0终止。但是,“buffer”中的数据(假设libmpq_file_getdata()执行它应该执行的操作)将包含整个文件或数据块或其他内容。

您如何确定您的char*数组正在被您称之为“截断”?如果您正在打印它或在调试器中查看它,它将看起来被截断,因为它将被视为字符串,由\0终止。但是,“缓冲区”中的数据(假设为libmpq\u file\u getdata()执行它应该执行的操作)将包含整个文件或数据块或任何内容。

抱歉,这些术语有点混乱(实际上不是memorybuffer,streambuffer的意思与代码中的一样)

是的,你说得对……我在异常处理中犯了一个错误。在第一段代码之后出现了以下内容:

// 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
//检查文件是否已打开
//如果(!mpf.is_open())
pair temp=memorybuf.buffer();
如果(温度优先)
抛出AdtException(ADT_parserr_EFILE);//无法打开该文件
注意缺少!在temp.first之前。我对抛出的异常感到惊讶,查看了streambuffer.。处的内部缓冲区的长度(C#background:p)不清楚。
很抱歉,它现在正在按预期工作。

很抱歉,这些术语有点混乱(实际上不是memorybuffer,streambuffer是代码中的意思)

是的,你说得对……我在异常处理中犯了一个错误。在第一段代码之后出现了以下内容:

// 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
//检查文件是否已打开
//如果(!mpf.is_open())
pair temp=memorybuf.buffer();
如果(温度优先)
抛出AdtException(ADT_parserr_EFILE);//无法打开该文件
注意缺少!在temp.first之前。我对抛出的异常感到惊讶,查看了streambuffer.。处的内部缓冲区的长度(C#background:p)不清楚。
很抱歉,它现在正在按预期工作。

此外,您提到“streambuffer”,但我在代码中没有看到。此外,您提到“streambuffer”,但我在代码中没有看到。我假设您指的是“bufferstream”,它与“memorybuffer”和“streambuffer”又不同:)作为未来C++冒险的提示,从代码中删除所有“使用”语句,使命名空间显式。这意味着更多的打字,但它确实会使代码的未来读者更容易(例如潜在堆栈溢出问题回答者)。我想你是说“BuffSerFipe”,这再一次不同于“MeimyBuffic”和“SturnBuffel:”,这是对未来C++冒险的暗示,从代码中删除所有“使用”语句,使命名空间显式。is意味着更多的输入,但它确实让未来的代码读者(比如潜在的堆栈溢出问题解答者)更容易看到类的来源。是的,谢谢你,我是个漫不经心的人--再一次阅读并没有那么大的伤害。。。