Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2008.02.10;
Скачать: [xml.tar.bz2];

Вниз

Помогите распаковать gzip   Найти похожие ветки 

 
Вопрошающий   (2007-10-28 02:00) [0]

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

пытался использовать функцию для распаковки строки сжатой zlib:
[code]
uses zlib;
...
function Unzlib(inpStr:string):string;
var
 OutBuf: Pointer;
 OutBytes: Integer;
 outstream:TStringStream;
begin
 OutStream:=TStringStream.create("");
 OutBuf := nil;
 try
   try
     DecompressBuf(pointer(InpStr), length(InpStr), 0, OutBuf, OutBytes);
     outStream.Write(OutBuf^, OutBytes);
   finally
     if OutBuf <> nil then FreeMem(OutBuf);
   end;
 outStream.Position := 0;
 Result:=outstream.DataString;
 finally
   OutStream.Free;
 end;
end;
[/code]

предварительно обрезавши первые 10 байт (сигнатура гзип), и добавивши 2 байта (сигнатура zlib), а также обрезавши последние 8 байт (CRC32+ISIZE) (RFC1952)
Но все равно не могу распаковать строку.
Возможно это из-за того что в zlib после самого сжатого потока должно быть 4 байта, где используется не CRC32, а ADLER32 (RFC1950). Но его естественно я никаким образом не смогу получить.

Может кто-нить подскажет, как все-таки распаковать данные, сжатые gzip, не используя сторонних компонентов?
Тем более что в WIN уже имеется библиотека gzip.dll, неплохо было бы ее задействовать, но вот ее описание не могу нигде найти.


 
Dimaxx ©   (2007-10-28 10:46) [1]


> вот ее описание не могу нигде найти

Плохо искал - погугли "gzip.dll+delphi" - выдаст море ссылок. Первые же 2-3 дают ответ.


 
Вопрошающий   (2007-10-28 18:21) [2]


> выдаст море ссылок.


ссылок-то море, но вот толку от них никакого...
Причем большая часть ссылок - это чьи-то аналогичные вопросы, причем с такими ответами как Ваш...  Прям рекурсия какая-то... :-)
только на Королевстве нашел целую кучу подобных вопросов с ответами, заключающими в себе перенаправление куда подальше, в т.ч. гугль и т.п.

Ну нашел я один пример на сях. Но честно говоря, я так и не понял его. Да и что-то он мне доверия не внушает.


 
Slym ©   (2007-10-29 06:10) [3]

FastReport\Source\frxGZip.pas


 
Slym ©   (2007-10-29 06:11) [4]

в 10Indy тоже есть GZip декомпресор


 
homm ©   (2007-10-29 06:16) [5]

> [0] Вопрошающий   (28.10.07 02:00)
> пытался использовать функцию для распаковки строки сжатой
> zlib:
> Но все равно не могу распаковать строку.

А должен был смочь?


 
Slym ©   (2007-10-29 08:49) [6]

Вопрошающий   (28.10.07 2:00)
предварительно обрезавши первые 10 байт  (сигнатура гзип)

Минимум 10 байт, на этом заголовок не кончается, из этих 10 байт выдергивается наличие доп заголовков/опций и их тоже нужно "вырезать"


 
Вопрошающий   (2007-10-29 18:23) [7]


> Минимум 10 байт, на этом заголовок не кончается, из этих
> 10 байт выдергивается наличие доп заголовков/опций и их
> тоже нужно "вырезать"


Я исходил из того что там должен быть именно минимум...
Это контент переданный хттп-сервером, только пожатый гзипом для экономии трафика... И вроде в этих 10 байтах не было флагов присутствия дополнительных заголовков/опций.


> homm ©   (29.10.07 06:16) [5]
> > [0] Вопрошающий   (28.10.07 02:00)
> > пытался использовать функцию для распаковки строки сжатой
>
> > zlib:
> > Но все равно не могу распаковать строку.
>
> А должен был смочь?


Ну не знаю. Теоретически в гзипе используется метод сжатия zlib, поэтому я предположил, что должно сработать.
В инете находил шаманский метод по превращению данных сжатых zlib в gzip.
Там предлагается обрезать первых 2 байта (сигнатура zlib), вставивши вместо них 10 байтов сигнатуры gzip. Правда там имелся небольшой прокол связанный с контрольной суммой. Но автор написал, что это не особо важно, так как при распаковке такого гзип-файла стандартными средствами архиватор ругнется, но тем не менее распакует...


> Slym ©   (29.10.07 06:11) [4]
> в 10Indy тоже есть GZip декомпресор


Хм. Спасибо за подсказку... Поищу...
Кстати в стандартной поставке с 7 Дельфи какой Инди идет?


 
Дмитрий Белькевич ©   (2007-10-30 02:20) [8]

В Jedi: TJclGZIPDecompressionStream. Работает без проблем.

В 7-ке стандартной идут 9-е либы. Только старые.


 
Вопрошающий   (2007-10-30 16:45) [9]


> В Jedi: TJclGZIPDecompressionStream. Работает без проблем.


Я понимаю что гугль рулит, но все-таки огромнейшая просьба дать ссылку...
Так как в наше время как найти не трудно, трудно скачать...


 
Вопрошающий   (2007-10-31 06:16) [10]


> В Jedi: TJclGZIPDecompressionStream. Работает без проблем.


Скачал. Поробовал. Но проблемы все-таки есть...
Все вроде нормально расжимает, но страшно ругается при попытке обращения к свойству SIZE (выдает что "seek is not an supported operation").
и я уже не знаю как мне человеческим образом узнать размер распакованных данных...


 
Вопрошающий   (2007-10-31 06:30) [11]

А при обращении к OriginalDataSize вылетает с "Stream read error"


 
Slym ©   (2007-10-31 06:39) [12]

Вопрошающий   (31.10.07 6:16) [10]
seek is not an supported operation

сначала разожми, потом спрашивай размер... т.к. изначально размер без распаковки не известен


 
Вопрошающий   (2007-10-31 14:47) [13]


> сначала разожми, потом спрашивай размер... т.к. изначально
> размер без распаковки не известен


Хм... Вобщем пишу так:


function GZipStringDecompress(InputString:string):string;
var
 SourceStream:TStringStream;
begin
 SourceStream:=TStringStream.Create(InputString);
 try
   with TJclGZIPDecompressionStream.Create(SourceStream) do
     try
       SetString(result,nil,Size);
       Read(Pointer(result)^, Size);
     finally
       Free;
     end;
  finally
    SourceStream.Free;
  end;
end;


подскажите плиз что тут нужно изменить/добавить...


 
Вопрошающий   (2007-10-31 14:53) [14]

Кстати, при выполнении:


> Read(Pointer(result)^, Size);


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


 
Вопрошающий   (2007-10-31 17:12) [15]

Вот нашел в гугле:
http://www.delphipraxis.net/topic109876.html

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


 
Virgo_Style ©   (2007-10-31 19:17) [16]

Первый пишет, что TStream - абстрактный предок и его использовать нельзя, что пишет второй - я перевести не могу, жди знатоков)


 
Вопрошающий   (2007-10-31 20:08) [17]

Насчет первого я понял, что он обратил внимание на TStream, и поэтому, хоть он и правильно заметил, тем не менее его ответ не относится к существу вопроса.
Интерестно все-таки насколько результативен второй ответ?


 
Virgo_Style ©   (2007-10-31 22:45) [18]

Попытался вникнуть. М-да-а-а... давно я не брал в руки шашек...

Ansonsten wart mal ab. Gerade wird in der JCL an JclCompression gebaut.

Иначе были далеко однажды. Как раз строится в JCL в JclCompression.
(c) Prompt.

М-да.

Первое предложение мне больше кажется похожим на "Погоди-ка" или "Или подожди". Не пойму, это фигура речи или рекомендация по теме.
Вторая фраза вроде похожа на "Именно так устроен в JCL [юнит] JCLCompression", если так, то первая фраза - именно рекомендация.

p.s. Вот же делать мне нечего...

Жаль, слишком давно я работал с ZLib, уже не помню деталей, а ведь была подобная проблема...

Минуточку. > обрезавши последние 8 байт (CRC32+ISIZE)
ISize - это не в нашу тему?

Или еще мысль - нельзя ли разжимать постепенно, проверяя при этом position в сжатом потоке?

На этом я откланиваюсь, бо результаты ночных раздумий по утрам читать обычно или странно, или стыдно =)


 
Вопрошающий   (2007-11-01 00:58) [19]


> ISize - это не в нашу тему?


Хм. Как-то я сразу до этого не додумался... получается что это уже один из вариантов решения вопроса... только вот он как-то выглядит череззаднепроходно... Но за неимением других вариантов возможно придется именно его и использовать.


 
Вопрошающий   (2007-11-01 03:16) [20]

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

Но при попытке написать все это более менее прилично выяснилось что метод seek почему-то не работает во всех наследниках TStream, в частности даже в TStringStream... Вобщем какие-то странные вещи...пока не могу понять с чем это связано...


 
Slym ©   (2007-11-01 04:23) [21]

Вопрошающий   (31.10.07 14:47) [13]
function GZipStringDecompress(const InputString:string):string;
var
 Source,Dest:TStringStream;
 Buf:array[byte] of byte;
 r:integer;
begin
 Dest:=TStringStream.Create("");
 try
   Source:=TStringStream.Create(InputString);
   try
     with TJclGZIPDecompressionStream.Create(Source) do
     try
       while true do
       begin
         r:=Read(Buf,SizeOf(Buf));
         if r<=0 then Break;
         Dest.WriteBuffer(Buf,r);
       end;
     finally
       Free;
     end;
   finally
     Source.Free;
   end;
   result:=Dest.DataString;
 finally
   Dest.Free;
 end;
end;


 
Вопрошающий   (2007-11-01 18:39) [22]


>        while true do
>        begin
>          r:=Read(Buf,SizeOf(Buf));
>          if r<=0 then Break;
>          Dest.WriteBuffer(Buf,r);
>        end;


Хм... Смысл мне не особо нравится... Но выглядит прилично... Да и работает...
Вобщем беру на вооружение этот вариант.

Спасибо!


 
SuperHacker   (2007-11-01 19:42) [23]


> нужно распаковать строку полученную при загрузке по хттп
> контента сжатого гзипом.

Я тоже долго с этим мучался, но потом решил проблему, используя zlib:

delete(s,1,pos(#13#10#13#10,s)+3);
s2:=GZDecompressStr(s);

В s лежит то, что сервер прислал, в s2 - раскодированный HTML.
В uses надо добавить ZlibExGz.


 
SuperHacker   (2007-11-01 20:29) [24]

Забыл дописать: вышеуказанный юнит для Delphi я взял здесь: http://www.base2ti.com/zlib.htm


 
Вопрошающий   (2007-11-01 22:11) [25]


> delete(s,1,pos(#13#10#13#10,s)+3);
> s2:=GZDecompressStr(s);


#13#10#13#10 ...
Это разделитель заголовка ответа хттп сервера от самих данных...
к гзип оно отношения не имеет...

А за ссылку спасибо... Попробовал. Отлично работает...



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2008.02.10;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.044 c
15-1200072995
vrem_
2008-01-11 20:36
2008.02.10
Нам пишут!


2-1200384521
Yury
2008-01-15 11:08
2008.02.10
richedit


2-1200677665
no_limit
2008-01-18 20:34
2008.02.10
Осуществить перенос текста мышью из Memo в Memo (MDI)


2-1200115481
Voya)
2008-01-12 08:24
2008.02.10
Загрузочная флешка


2-1200290731
Dana
2008-01-14 09:05
2008.02.10
111





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский