увеличить буфер памяти и массив символов - PullRequest
1 голос
/ 12 января 2010

В настоящее время я распаковываю один из файлов .mpq от Blizzard для чтения. Для доступа к распакованному буферу символов я использую boost :: interprocess :: stream :: memorybuffer. Поскольку файлы .mpq имеют чанкованную структуру, всегда начинающуюся с заголовка версии (обычно 12 байтов, см. http://wiki.devklog.net/index.php?title=The_MoPaQ_Archive_Format#2.2_Archive_Header), Представление массива char *, похоже, усекается при первом \ 0, даже если размер файла (что-то около 1,6 МБ) остается постоянным и (вероятно) всегда выделяется. Результатом является потоковый буфер с эффективной длиной 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 Надеюсь получить удобный ответ (пожалуйста, не предлагайте переписывать libmpq и лежащую в основе архитектуру zlib ^^). Класс MPQFile и лежащие в его основе несжатые методы фактически взяты из рабочего проекта, поэтому ошибка заключается либо в использовании буфера с классом streambuffer, либо во внутренней арифметике с массивом символов, которую я не имею ни малейшего понятия. Кстати, в чем разница между использованием знаковых / беззнаковых символов в качестве буферов данных? Имеет ли это какое-либо отношение к моей проблеме (вы можете видеть, что в коде случайные символы char * unsigned char * принимаются в качестве аргументов функции) Если вам нужно больше информации, не стесняйтесь спрашивать:)

Ответы [ 2 ]

1 голос
/ 12 января 2010

Как вы определяете, что ваш массив * char 'усекается', как вы его называете?Если вы распечатываете его или просматриваете в отладчике, он будет выглядеть усеченным, потому что он будет обрабатываться как строка, которая заканчивается \ 0.Однако данные в «буфере» (при условии, что libmpq_file_getdata () делает то, что должны делать) будут содержать весь файл или блок данных или что угодно.

0 голосов
/ 12 января 2010

Извините, немного перепутал эти термины (на самом деле не буфер памяти, а потоковый буфер, как в коде)

Да, ты прав ... У меня была ошибка в обработке исключений. Сразу после этого появляется первый бит кода:

// 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

заметить пропавших без вести! до темп. Я был удивлен сгенерированным исключением, посмотрел на буфер потока .. Внутренний буфер был перепутан с его длиной (C # background: P). Извините за это, теперь он работает как ожидалось.

...