我目前正在解压暴雪的一个 .mpq 文件以供阅读。 为了访问解压缩的字符缓冲区,我使用了 boost::interprocess::stream::memorybuffer。 因为 .mpq 文件具有始终以版本 header 开头的分块结构(通常为 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 类和底层的解压缩方法实际上是从一个工作项目中获取的,所以错误要么是在使用 streambuffer 类的缓冲区的某个地方,要么是我不知道的 char 数组算法的内部问题。 顺便问一下,使用有符号/无符号字符作为数据缓冲区有什么区别?与我的问题有什么关系(您可能会看到,在代码中随机将 char* unsigned char* 作为函数参数) 如果您需要更多信息,请随时询问 :)
最佳答案
您如何确定您的 char* 数组被“截断”了?如果您正在打印它或在调试器中查看它,它将看起来 被截断,因为它将被视为一个字符串,以\0 终止。但是,“缓冲区”中的数据(假设 libmpq_file_getdata() 执行它应该执行的操作)将包含整个文件或数据 block 或其他内容。
关于c++ - boost 内存缓冲区和字符数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2049944/