Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.02.10;
Скачать: CL | DM;

Вниз

Помогите распаковать 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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.021 c
15-1200080417
Черный Шаман
2008-01-11 22:40
2008.02.10
Билинейная или бикубическая фильтрация с учетом TransparentColor


15-1199355046
(MiTch)
2008-01-03 13:10
2008.02.10
Установка компонента Hhopen.


2-1200391223
Lamer666
2008-01-15 13:00
2008.02.10
MDI и ActionMeneger+ActionMainMenuBar


2-1200477243
Washington
2008-01-16 12:54
2008.02.10
Сворачивание формы


8-1173263139
homm
2007-03-07 13:25
2008.02.10
Geometrical Pen