Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2015-11

GZip issues

7 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Werner Pamler

In the LazarusMailingListReader, I am decompressing the downloaded gzip mail archives by using the Abbrevia package. This is working fine in Windows, but Linux rejects to compile the package due to an "identifier nl_langinfo not found" error in this procedure of unit AbCharset:

function AbSysCharSetIsUTF8: Boolean;
begin
   {$IFDEF DARWIN}
   Result := True;
   {$ENDIF}
   {$IFDEF MSWINDOWS}
   Result := False;
   {$ENDIF}
   {$IFDEF LINUX}
   Result := StrComp(nl_langinfo(_NL_CTYPE_CODESET_NAME), 'UTF-8') = 0;
   {$ENDIF}
end;

As I found out "nl_langinfo" belongs to libc, and in fact, this can be activated by a define in the package, but this in turn causes other compilation errors. My question: Is there a funtion in the standard fpc units with the same functionality?

Another question: I would prefer to avoid Abbrevia altogether and use the standard zip support in fpc. There are examples in the wiki on how to use the TDecompressionStream for inflating gzip files. But I always get a "data error"at least with the mailinglist archive files from http://lists.lazarus.freepascal.org/pipermail/lazarus/. If I use a TGZFileStream instead of the TDecompressionStream by a TGZFileStream, then the file decompresses fine. But this is not a good solution as I would have to use temporary files which I want to avoid. How can the TGZFileStream be modified such that it accepts a stream as input parameter instead of a filename?

Reply by email

Rik van Kekem
to Werner Pamler
Werner Pamler wrote 10 lines
Another question: I would prefer to avoid Abbrevia altogether and use the standard zip support in fpc. There are examples in the wiki on how to use the TDecompressionStream for inflating gzip files. But I always get a "data error"at least with the mailinglist archive files from http://lists.lazarus.freepascal.org/pipermail/lazarus/. If I use a TGZFileStream instead of the TDecompressionStream by a TGZFileStream, then the file decompresses fine. But this is not a good solution as I would have to use temporary files which I want to avoid. How can the TGZFileStream be modified such that it accepts a stream as input parameter instead of a filename?

It should be possible to use inflateInit2 from paszlib. I've found a snippet here: http://www.gocher.me/GZIP

If you take GZIPUtils.pas, at first you think it should work, but it didn't. The only thing I found was that that code only takes a header of 9 bytes into account while the 2015-November.txt.gz has a header of 71 bytes. So if I change the following in ZUncompressStream I could successfully extract 2015-November.txt:

On line 178:
     // inStream.Position := 10; // jump over header
     inStream.Position := 72; // jump over header, this needs to be
adjusted to read a string until #0
========
procedure TForm1.Button1Click(Sender: TObject);
var
   inStream, outStream: TMemoryStream;
begin
   inStream := TMemoryStream.Create;
   outStream := TMemoryStream.Create;
   try
     inStream.LoadFromFile('c:\temp\2015-November.txt.gz');
     if ZUncompressStream(inStream, outStream) then
     begin
       outStream.SaveToFile('c:\temp\2015-November.txt');
     end;
   finally
     inStream.Free;
     outStream.Free;
   end;
end;
========
Of course in your final code you should read a string until #0 from the
file and position it correctly to begin at the real data.

You could also strip the deflate-part of that unit (or completely create your own implementation from this source). It's not much code after you strip all the things you don't need.

Grtz,
/Rik/ (rvk on forum)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20151116/e1cb5264/attachment.html>

Reply by email

Werner Pamler
to Rik van Kekem
Rik van Kekem wrote 7 lines
It should be possible to use inflateInit2 from paszlib. I've found a snippet here: http://www.gocher.me/GZIP If you take GZIPUtils.pas, at first you think it should work, but it didn't. The only thing I found was that that code only takes a header of 9 bytes into account while the 2015-November.txt.gz has a header of 71 bytes.

Thanks, Rik, for pointing this out to me. I had seen this site yesterday, but was too much scared of the gzip format to find the details of the extended header... The LazarusMailingListReader now is no longer dependent on Abbrevia and runs fine on Linux. -------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20151116/0de521c4/attachment-0001.html>

Reply by email

Ondrej Pokorny
to Werner Pamler: In the LazarusMailingListReader, I am decompressing the downloaded gzip mail archives by…
Werner Pamler wrote
Another question: I would prefer to avoid Abbrevia altogether and use the standard zip support in fpc.

Lazarus doesn't include support for ZIP files, AFAIK. A ZIP file is a container of compressed streams. So you have to parse the ZIP file structure and then use TDecompressionStream on the stream you want to decompress.

I wrote a decent ZIP wrapper unit for FPC and Delphi. In FPC it uses "paszlib", in Delphi it uses "System.ZLib".
But it depends on some of my internal classes. Maybe I will rewrite it so that it could be included into FCL. But I really have a lot of work now :(

Ondrej

Reply by email

Michael Van Canneyt
to Ondrej Pokorny: Lazarus doesn't include support for ZIP files, AFAIK. A ZIP file is a container of…
Ondrej Pokorny wrote 12 lines
On 15.11.2015 22:11, Werner Pamler wrote: > Another question: I would prefer to avoid Abbrevia altogether and use the > standard zip support in fpc. Lazarus doesn't include support for ZIP files, AFAIK. A ZIP file is a container of compressed streams. So you have to parse the ZIP file structure and then use TDecompressionStream on the stream you want to decompress. I wrote a decent ZIP wrapper unit for FPC and Delphi. In FPC it uses "paszlib", in Delphi it uses "System.ZLib". But it depends on some of my internal classes. Maybe I will rewrite it so that it could be included into FCL. But I really have a lot of work now :(

Since many years, FPC has a zipper unit which contains zip and unzip functionality.

Michael.

Reply by email

Ondrej Pokorny
to Michael Van Canneyt
Michael Van Canneyt wrote
Since many years, FPC has a zipper unit which contains zip and unzip functionality.

Great! Thanks for the correction. I just found it.

(I remembered it wrongly - it's already some time ago. I wrote a custom Zip wrapper because I needed one unit compatible with both Delphi and FPC. I also needed some extra features. Sorry for the wrong information.)

Ondrej

Reply by email