Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > qCompress как распаковать?


Автор: Mr_Devil 18.3.2012, 03:41
Есть приложение, которое экспортирует свои данные в XML-файл, но предварительно сжимает его:
Код

QByteArray compressedArray=qCompress(byteArray,9);
exportFile.write(compressedArray);
exportFile.close();

Распаковывает она все это дело обратно таким образом:
Код

QByteArray byteArray=qUncompress(fileImport.readAll());

Каким образом можно самостоятельно распаковать файл не имея фреймворка Qt?
Архиваторы его не распознают, видимо, не хватает заголовков. В папке с программой есть библиотека QtCore4.dll v4.7, в ней есть функции compress и uncompress. Попытки воспользоваться этими функциями на Delphi пока ни к чему не привели, т.к. реализации класса QByteArray в Delphi нет.

Подскажите, пожалуйста, как можно решить проблему? Может есть другие библиотеки с заголовками для Delphi, которые можно использовать?

З.Ы.: C++ не владею, фреймворка нет.



Автор: borisbn 18.3.2012, 10:06
Делаешь dll-ку на Си++, использующую Qt и экспортирующую 2 функции
Код
char* uncompress_wrap( const char * data, unsigned int dataSize, unsigned int * uncompressedSize );
void clean_after_uncompress( char*);

Первая будет делать следующее
Код

char* uncompress_wrap( const char * data, unsigned int dataSize, unsigned int * uncompressedSize ) {
    QByteArray ba = qUncompress( QByteArray( data, dataSize ) );
    *uncompressedSize = ba.size();
    char * p = new char[ *uncompressedSize ];
    memcpy( p, ba.constData(), *uncompressedSize );
    return p;
}

Вторая:
Код

void clean_after_uncompress( char * p ) {
    delete []p;
}

Как в дельфи подключить обычную dll-ку и импортировать оттуда функции не знаю, но, думаю, это - несложно

Автор: boostcoder 18.3.2012, 10:10
Цитата(Mr_Devil @  18.3.2012,  03:41 Найти цитируемый пост)
Каким образом можно самостоятельно распаковать файл не имея фреймворка Qt?

http://qt.gitorious.org/qt/qt/blobs/4.8/src/corelib/tools/qbytearray.cpp#line526.

Цитата(Mr_Devil @  18.3.2012,  03:41 Найти цитируемый пост)
есть функции compress и uncompress

по всей видимости, это экспорт функций zlib.

Автор: borisbn 18.3.2012, 10:21
Цитата(boostcoder @  18.3.2012,  10:10 Найти цитируемый пост)
по всей видимости, это экспорт функций zlib

ага. единственно что - они добавляют к данным 4 байта - размер распакованных данных. если их отрезать, то можно пользоваться zlib-ом. я уже так делал. работатет

Автор: Sahab 18.3.2012, 12:25
Цитата(borisbn @  18.3.2012,  10:21 Найти цитируемый пост)
они добавляют к данным 4 байта

зочем?

Автор: borisbn 18.3.2012, 13:43
Цитата(Sahab @  18.3.2012,  12:25 Найти цитируемый пост)
зочем? 

наверное, чтобы при распаковке заранее знать размер данных

Автор: Mr_Devil 18.3.2012, 23:47
Цитата(borisbn @ 18.3.2012,  10:06)
Делаешь dll-ку на Си++, использующую Qt и экспортирующую 2 функции

Идея хорошая, но даже если я найду компилятор, у меня нет самого фреймворка, где объявлены все эти классы и функции (QByteArray, qUncompress). К тому же в C++ я, можно сказать, мало что понимаю smile

Цитата(borisbn @ 18.3.2012,  10:06)
Как в дельфи подключить обычную dll-ку и импортировать оттуда функции не знаю, но, думаю, это - несложно

Не сложно, я хотел использовать напрямую библиотеку QtCore4.dll, но не знаю какие параметры передавать, в каком порядке и каких типов.

Может быть можно что-то к этому архиву дописать, чтобы можно было открыть каким-нибудь архиватором?

Цитата(boostcoder @ 18.3.2012,  10:10)
Цитата(Mr_Devil @  18.3.2012,  03:41 Найти цитируемый пост)
Каким образом можно самостоятельно распаковать файл не имея фреймворка Qt?

http://qt.gitorious.org/qt/qt/blobs/4.8/src/corelib/tools/qbytearray.cpp#line526.

Не совсем понял что там написано. Это реализация qUncompress? В исходном тексте (в моем первом сообщении) передается только 1 параметр. Почему там 2 параметра и чем это может помочь? Предлагаете самостоятельно сделать реализацию всех используемых классов на Делфи?

Цитата(boostcoder @ 18.3.2012,  10:10)
Цитата(Mr_Devil @  18.3.2012,  03:41 Найти цитируемый пост)
есть функции compress и uncompress

по всей видимости, это экспорт функций zlib.

Есть где почитать, что им можно передавать и как забирать?

Цитата(borisbn @ 18.3.2012,  10:21)
Цитата(boostcoder @  18.3.2012,  10:10 Найти цитируемый пост)
по всей видимости, это экспорт функций zlib

ага. единственно что - они добавляют к данным 4 байта - размер распакованных данных. если их отрезать, то можно пользоваться zlib-ом. я уже так делал. работатет

Если воспользоваться zlib'ом, можно будет извлечь данные, не зная исходного размера?

Автор: borisbn 19.3.2012, 08:47
Цитата(Mr_Devil @  18.3.2012,  23:47 Найти цитируемый пост)
Есть где почитать, что им можно передавать и как забирать?

http://zlib.net/manual.html

Цитата(Mr_Devil @  18.3.2012,  23:47 Найти цитируемый пост)
Если воспользоваться zlib'ом, можно будет извлечь данные, не зная исходного размера?

можно. отрезаешь первые 4 байта и отдаёшь остаток в ф-цию распаковки zlib'а. единственное что - при смене библиотеки Qt они могут сменить формат и такой рукоблудный qUncompress работать не будет. так что лучше воспользуйся способом из моего первого сообщения

Автор: Mr_Devil 19.3.2012, 16:31
Цитата(borisbn @ 19.3.2012,  08:47)
Цитата(Mr_Devil @  18.3.2012,  23:47 Найти цитируемый пост)
Если воспользоваться zlib'ом, можно будет извлечь данные, не зная исходного размера?

можно. отрезаешь первые 4 байта и отдаёшь остаток в ф-цию распаковки zlib'а. единственное что - при смене библиотеки Qt они могут сменить формат и такой рукоблудный qUncompress работать не будет. так что лучше воспользуйся способом из моего первого сообщения

Спасибо за помощь, все получилось. Отрезал 4 байта и распаковал ZLib'ом. Библиотека Qt не поменяется, т.к. приложение я обновлять не собираюсь, мне нужно было только разобрать его формат экспорта, чтобы слепить для него файл импорта со своими данными. Теперь с библиотекой ZLib автоматически решился второй вопрос "Чем запаковать обратно?" smile

Скомпилированную библитеку ZLib взял http://www.winimage.com/zLibDll/index.html. Это ссылка с сайта http://zlib.net.
Обертку библиотеки для Delphi взял http://www.base2ti.com/?id=delphi.zlib. Эту ссылку я тоже нашел на сайте ZLib.

получился такой вот код:
Код

...
uses ZLibEx, ZLibExApi
...
procedure TForm1.FormCreate(Sender: TObject);
var
  FileIn,FileOut: THandle;
  PArrIn, PArrOut: Pointer;
  i: Cardinal;
begin
  FileIn:=CreateFile('123.rcp',GENERIC_READ,0,nil,OPEN_EXISTING,0,0);
  i:=GetFileSize(FileIn,nil)-4;
  PArrIn:=AllocMem(i);
  FileSeek(FileIn,4,0);
  ReadFile(FileIn,PArrIn^,i,i,nil);
  CloseHandle(FileIn);
  ZDecompress(PArrIn,i,PArrOut,Integer(i));
  FreeMem(PArrIn);
  FileOut:=CreateFile('123.rcp.xml',GENERIC_WRITE,0,nil,CREATE_ALWAYS,0,0);
  WriteFile(FileOut,PArrOut^,i,i,nil);
  FreeMem(PArrOut);
  CloseHandle(FileOut);
end;


З.Ы.: Есть такая утилита WinHEX, там в меню Edit -> Convert есть вариант конвертации "zlib inflate". Отрезаем у файла первые 4 байта, потом делаем конвертацию и получаем такой же результат как и у ZLib'а smile Это первое из того что мне было нужно - убедиться что там всетаки XML.

З.З.Ы.: К сожалению, у меня не хватает постов для плюсования тех, кто помогал  smile 

Автор: boostcoder 19.3.2012, 16:57
маладца что решение выложил!

Цитата(Mr_Devil @  19.3.2012,  16:31 Найти цитируемый пост)
К сожалению, у меня не хватает постов для плюсования тех, кто помогал

успеешь)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)