uncompress из zlib

Тема в разделе "WASM.WIN32", создана пользователем 10_Brasil, 16 ноя 2006.

  1. 10_Brasil

    10_Brasil New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    54
    Кто пользовался zlib`ом - подскажите как правильно пользоваться функцией uncompress. Вот я качаю данные с веба, как узнать их реальный размер? Чтобы выделить память под распаковку?

    Вот цитата из русского мана
     
  2. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    я для своих нужд переписал zlib на асм так, что принимаются только два параметра - входной и выходной буферы, на сях проблематично будет убрать размеры (хотя они при распаковке нафиг не нужны) т.к. завязано много на них, хотя и можно, если убить часа 3-4.
    А так обычно сжатый и несжатый размеры хранятся, для тех хе архивов
     
  3. 10_Brasil

    10_Brasil New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    54
    Поясни как не нужны?
     
  4. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    ну вот так - не нужны, для злиб размер распаковываемых данных не важен, когда остановиться и так будет видно, а размер выходного буфера нужен только для проверки выхода за границу доступной области, вот и все
     
  5. 10_Brasil

    10_Brasil New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    54
    Видимо я чегото не догоняю, объясни плиз, вот код, на котором я тестирую функцию uncompress

    Код (Text):
    1.     FILE *f;
    2.    
    3.  
    4.     if(f = fopen("D:\\tmp96.tmp","rb")) // D:\\tmp96.tmp - запакованный файл, (я сохраняю то что мне присылает сайт)
    5.     {
    6.         LPSTR lpMem;
    7.         DWORD dwSize = _filelength(f->_file);
    8.         char buffer[MAX_PATH];
    9.        
    10.         if(lpMem = (LPSTR) malloc(dwSize))
    11.         {
    12.             fread(lpMem,dwSize,1,f);
    13.             DWORD i=0;
    14.            
    15.             int t = uncompress((unsigned char *) &buffer,&i,(unsigned char *) lpMem,dwSize);
    16.            
    17.             if(t == Z_OK)
    18.             {
    19.                 MessageBox(0,"Z_OK",0,0);
    20.             }
    21.             else if(t == Z_MEM_ERROR)
    22.             {
    23.                 MessageBox(0,"Z_MEM_ERROR",0,0);
    24.             }
    25.             else if(t == Z_BUF_ERROR)
    26.             {
    27.                 MessageBox(0,"Z_BUF_ERROR",0,0);
    28.             }
    29.             else if(t == Z_DATA_ERROR)
    30.             {
    31.                 MessageBox(0,"Z_DATA_ERROR",0,0);
    32.             }
    33.            
    34.             free(lpMem);
    35.         }
    36.        
    37.         fclose(f);
    38.     }
    Вот почему постоянно выдается Z_DATA_ERROR, что я не так делаю?
     
  6. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    а что, сайты сразу же чистый поток выдают? там gzip - заголовок какой-то ведь есть, а поток уже после него идет
     
  7. 10_Brasil

    10_Brasil New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    54
    uncompress - уже с потоком работает? как добратся до потока минуя заголовки?
    можешь подкинуть примерчик?
     
  8. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    гугли формат гзип, но заголовок там кажется фиксированный и равен 8 байт - пропускаешь их и идет поток, в первых 8ми байтах - распакованный размер. Но это по памяти, могу ошибиться
     
  9. gazlan

    gazlan Member

    Публикаций:
    0
    Регистрация:
    22 май 2005
    Сообщения:
    414
    Вот здесь есть работающий пример.
     
  10. 10_Brasil

    10_Brasil New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    54
    gazlan
    Пример твой смотрел, вопрос по структуре ZIP_LOCAL_FILE_HEADER, судя по твоему коду ZipStream.avail_in = pLFHeader->_dwPackSize; в структуре ZIP_LOCAL_FILE_HEADER _dwPackSize - это размер незапакованного файла, я же нашел только такую структуру и поля тут нет такого

    Код (Text):
    1. #pragma pack(push, 1)
    2. struct zip_local_file_header
    3. {
    4.     DWORD header_sig;// 4bytes (0x04034b50)
    5.     WORD version;// needed to extract   2 bytes
    6.     WORD general_flags;// purpose bit flag  2 bytes
    7.     WORD compression_method;//  2 bytes
    8.     WORD last_mod_file_time;//  2 bytes
    9.     WORD last_mod_file_date;//  2 bytes
    10.     DWORD crc32;//-32   4 bytes
    11.     DWORD compressed_size; //   4 bytes
    12.     DWORD uncompressed_size; //     4 bytes
    13.     WORD file_name_length; //   2 bytes
    14.     WORD extra_field_length; //     2 bytes
    15.     //char *file_name; //   (variable size)
    16.     //char *extra_field; //     (variable size)
    17. };
    18. #pragma pack(pop)
    masquer
    Все что мне удалось найти по gzip
    Код (Text):
    1. typedef struct gz_header_s {
    2.     int     text;       /* true if compressed data believed to be text */
    3.     uLong   time;       /* modification time */
    4.     int     xflags;     /* extra flags (not used when writing a gzip file) */
    5.     int     os;         /* operating system */
    6.     Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
    7.     uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
    8.     uInt    extra_max;  /* space at extra (only when reading header) */
    9.     Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
    10.     uInt    name_max;   /* space at name (only when reading header) */
    11.     Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
    12.     uInt    comm_max;   /* space at comment (only when reading header) */
    13.     int     hcrc;       /* true if there was or will be a header crc */
    14.     int     done;       /* true when done reading gzip header (not used
    15.                            when writing a gzip file) */
    16. } gz_header;
    но чтото не похоже чтоб в нем хранился реальный размер файла

    В аттаче запакованный файл gzip`ом если кто может помочь приведите рабочий пример как его распаковать ч-з uncompress или inflate, распаковка ч-з gzopen и т.д. проходит нормально, но не хочется связыватся с файлами, я хочу работать только с памятью.
     
  11. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    да, тут я был неправ (про хранение в начале). Короче, чтоб распаковать, компилируй злиб с GUNZIP и можешь ему сам файл подсовывать (реальный размер на тех хтмл, которые в гзипе отдаются пишется в самый последний дворд)
     
  12. gazlan

    gazlan Member

    Публикаций:
    0
    Регистрация:
    22 май 2005
    Сообщения:
    414
    Как и следует из названия, это размер _упакованного_ блока. Unpacked size при распаковке, вообще говоря, неважен - лишь бы хватило буфера, чтобы не гонять в цикле.
     
  13. Scratch

    Scratch New Member

    Публикаций:
    0
    Регистрация:
    1 янв 2005
    Сообщения:
    161
    поищи дельфевую либу fastzlib, там есть пример работы именно с серверным сжатием\расжатием
     
  14. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    10_Brasil
    В аттаче запакованный файл gzip`ом если кто может помочь приведите рабочий пример как его распаковать
    В аттаче пример на Си.
    zlib1.dll и zlib1.lib получены из zlib122.
     
  15. 10_Brasil

    10_Brasil New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    54
    q_q
    Спасибо за пример, только я писал выше что с gzopen, gzread и т.д. я работать сразу научился (опыт php помог), т.е. проблем с этим конкретно нет, другое дело, что я пишу программу, которая периодически скачивает страницу с сайта (он собственно кодирует страницу в gzip), и мне важно распаковывать данные налету, а не сохранять на диск а затем считывать...
     
  16. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    10_Brasil
    См. аттач.
    Функция ungz (аналог zlib.uncompress) с проверкой наличия заголовка (этим zlib.uncompress отличается от zlib.gzopen). Правда проверить все поля заголовка не удалось, мой gzip умет (или у меня хватает ума его заставить) добавить в заголовок только FLG.FNAME.
     
  17. 10_Brasil

    10_Brasil New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    54
    q_q
    Спасибо
     
  18. 10_Brasil

    10_Brasil New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    54
    Еще ковыряя всю эту тему наткнулся на библиотеки wwwlib и libcurl,
    что касается второй то то можно смело сказать что это лучший выбор для лентяев, все делает за меня, учитывая что довелось поработать и wininet, winhttp, и просто с сокетами - libcurl пока лучшее что я видел (если скомпилировать с zlib`ом то автоматом распаковывает данные, естественно если указать curl_easy_setopt(curl_handle, CURLOPT_ENCODING, "gzip,deflate");).