我目前正在解压暴雪的 .mpq 文件之一以供阅读。为了访问解压的字符缓冲区,我使用了 boost::interprocess::stream::memorybuffer。因为 .mpq 文件具有始终以版本标头开头的分块结构(通常为 12 个字节,请参阅http://wiki.devklog.net/index.php?title=The_MoPaQ_Archive_Format#2.2_Archive_Header),char* 数组表示似乎被截断在第一个 \0,即使文件大小(大约 1.6mb)保持不变并且(可能)总是分配。结果是一个有效长度为 4 的流缓冲区('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;
}
}
也许有人可以帮助我。我对 STL 和 boost 编程真的很陌生,而且无论如何也没有 C++ 编程经验:P 希望得到一个方便的答案(请不要建议重写 libmpq 和底层的 zlib 架构^^)。MPQFile 类和底层的 uncompress 方法实际上是从一个工作项目中获取的,所以错误要么是在使用 streambuffer 类的缓冲区中的某个地方,要么是我不知道的 char 数组算法内部的东西。顺便说一句,使用有符号/无符号字符作为数据缓冲区有什么区别?与我的问题有什么关系(您可能会看到,在代码中随机 char* unsigned char* 被视为函数参数)如果您需要更多信息,请随时询问:)