Recent

Author Topic: Unzip from a stream  (Read 17082 times)

wpflum

  • Sr. Member
  • ****
  • Posts: 276
Re: Unzip from a stream
« Reply #15 on: April 10, 2014, 04:22:29 pm »
Cool, I thought there was a way but my understanding of streams is almost non existent and I'm not that good with digging into other peoples code, I use basics so some of the stuff just plain eludes me.  I was trying look at the zipper.pas but since I assumed I needed a procedure other than Tunzipper for a stream I didn't look very hard at the code itself.

Another day another bit of info added to the old noggin, if this keeps up I'll have to  lose some of the basics like shoelace tying and utensil use just to have room.

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Unzip from a stream
« Reply #16 on: April 10, 2014, 05:01:03 pm »
I'm back to the 'all the time' issue.  I asked three unrelated questions, if that is 'all the time' in your book I apologize for monopolizing your time and inundating the forum.
Please excuse me.
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

wpflum

  • Sr. Member
  • ****
  • Posts: 276
Re: Unzip from a stream
« Reply #17 on: April 10, 2014, 07:08:08 pm »
WOOHOO.  It's amazing how things work when I, somewhat, understand them! 

Is they way the zipper.pas module is written normal for this kind of thing?  I just find it strange that setting or passing a stream is different than setting the file name.  Why wouldn't you just write a function to take the stream in and use it the same way.  Is this something related to streams in general?  This is the first time I've dealt with streams so I'm kinda lacking in depth of knowledge. 

hinst

  • Sr. Member
  • ****
  • Posts: 303
Re: Unzip from a stream
« Reply #18 on: April 10, 2014, 07:15:02 pm »
So does it work for you now?
TUnZipper class is implemented like it is because its authors decided to implement it this way. It was their decision; what were they thinking I have no idea. Maybe one could come up with a better implementation of this class. I don't know.

Could be better, could be worse....
« Last Edit: April 10, 2014, 07:20:01 pm by hinst »
Too late to escape fate

wpflum

  • Sr. Member
  • ****
  • Posts: 276
Re: Unzip from a stream
« Reply #19 on: April 10, 2014, 07:21:51 pm »
Yep, works like a charm.

 I get that is was the authors choice I was just wondering if there was any underlying reason like speed, memory usage, etc.  Lots of times when I try to decode someone else’s code I wonder why they did it that way.  I normally assume that the person writing the code is more versed in coding than I am so there might be a reason other than personal choice that is was done the way it was. 

hinst

  • Sr. Member
  • ****
  • Posts: 303
Re: Unzip from a stream
« Reply #20 on: April 10, 2014, 08:15:04 pm »
Perhaps using event handlers in this case was not really necessary. I personally would just let user assign input stream to a property, then provide output stream as an argument
Using event handlers is common enough, but in this case I don't think it is necessary
When I don't like author's approach to class design, I tend to write my own wrapper classes or functions which provide more convenient (or simplier) access to library features for me
Too late to escape fate

Ove Halseth

  • Newbie
  • Posts: 6
Re: Unzip from a stream
« Reply #21 on: March 30, 2017, 11:31:30 am »
I'm unable to wrap my head around using the OnOpenInputStream.

What I'm trying to do is zip files to stream - encrypt stream and save to file. This I have done, but the reverse: decrypt file to stream - unzip stream is throwing me off at the unzip stream bit  :(

Have searched for an working example where OnOpenInputStream is used, but no luck.

So if some of you guys could give an simple example it would be great  :)

Handoko

  • Hero Member
  • *****
  • Posts: 5122
  • My goal: build my own game engine using Lazarus
Re: Unzip from a stream
« Reply #22 on: March 30, 2017, 01:01:40 pm »
Hello Ove Halseth,
Welcome to this forum.

This maybe is what you're looking for:
http://wiki.freepascal.org/paszlib#Unzip_file_to_a_stream

Ove Halseth

  • Newbie
  • Posts: 6
Re: Unzip from a stream
« Reply #23 on: March 30, 2017, 01:46:11 pm »
Hello Ove Halseth,
Welcome to this forum.
Thank you :)
Quote
This maybe is what you're looking for:
http://wiki.freepascal.org/paszlib#Unzip_file_to_a_stream
I found that example but unfortunately I need unzip file from a stream.

Ove Halseth

  • Newbie
  • Posts: 6
Re: Unzip from a stream
« Reply #24 on: March 30, 2017, 01:49:59 pm »
Yep, works like a charm.

 I get that is was the authors choice I was just wondering if there was any underlying reason like speed, memory usage, etc.  Lots of times when I try to decode someone else’s code I wonder why they did it that way.  I normally assume that the person writing the code is more versed in coding than I am so there might be a reason other than personal choice that is was done the way it was.
I would be grateful if you could share an example with that show how to use OnOpenInputStream

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Unzip from a stream
« Reply #25 on: March 30, 2017, 01:59:52 pm »
I cannot answer for OnOpenInputStream. But unzipping to stream is heavily used in the fpspreadsheet package. The code is in unit fpsxmlcommon (https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/fpspreadsheet/source/common/fpsxmlcommon.pas); the class TStreamUnzipper requires the zipper unit and should be self-contained. Apply it as in UnzipToStream found in the same unit.

Ove Halseth

  • Newbie
  • Posts: 6
Re: Unzip from a stream
« Reply #26 on: March 30, 2017, 02:01:34 pm »
Here is an excerpt of my code:
    msOut:= TMemoryStream.Create;
    msData := TMemoryStream.Create;
    msData.LoadFromFile(ZipName);
    Cipher:= TDCP_rc4.Create(Self);
    Cipher.InitStr(KeyStr,TDCP_sha1); // initialize the cipher with a hash of the passphrase
    Cipher.DecryptStream(msData,msOut,msData.Size); // encrypt the contents of the file
    Cipher.Burn;
    Cipher.Free;
    uz := TUnZipper.Create;
    uz.OnOpenInputStream := UnzipStream; //<-- What do I do here? I have the stream as a local variable...
    uz.UnZipAllFiles;
    uz.Free;
    msOut.Free;
    msData.Free;

Handoko

  • Hero Member
  • *****
  • Posts: 5122
  • My goal: build my own game engine using Lazarus
Re: Unzip from a stream
« Reply #27 on: March 30, 2017, 02:21:52 pm »
Actually, some months ago I did some research about compress/decompressing data in memory using TZipper/TUnZipper. But due to some reasons, which I forget, I abandon it. Now I use TCompressionStream from ZStream unit.

If you still interested to use TZipper/TUnZipper, here I have a backup of the code:

Code: Pascal  [Select][+][-]
  1. unit StreamCompress;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10. function ZipData(const Input: TMemoryStream; Size: LongInt;
  11.   var Output: TMemoryStream; OutputReturn: Boolean = True): LongInt;
  12. function UnZipData(const Input: TMemoryStream; Size: LongInt;
  13.   var Output: TMemoryStream; OutputReturn: Boolean = True): LongInt;
  14.  
  15. implementation
  16.  
  17. uses
  18.   zipper, zstream;
  19.  
  20. type
  21.  
  22.   { TZipperClass }
  23.  
  24.   TZipperClass = class
  25.   strict private
  26.     FInputStream: TMemoryStream;
  27.     FOutputStream: TMemoryStream;
  28.     FResultStream: TMemoryStream;
  29.     procedure DoCreateOutZipStream(Sender: TObject; var AStream: TStream;
  30.       AItem: TFullZipFileEntry);
  31.     procedure DoDoneOutZipStream(Sender: TObject; var AStream: TStream;
  32.       AItem: TFullZipFileEntry);
  33.     procedure DoOpenInputStream(Sender: TObject; var AStream: TStream);
  34.   public
  35.     function Zip(const Input: TMemoryStream; Size: LongInt;
  36.       var Output: TMemoryStream; OutputReturn: Boolean): LongInt;
  37.     function UnZip(const Input: TMemoryStream; Size: LongInt;
  38.       var Output: TMemoryStream; OutputReturn: Boolean): LongInt;
  39.   end;
  40.  
  41. procedure TZipperClass.DoCreateOutZipStream(Sender: TObject;
  42.   var AStream: TStream; AItem: TFullZipFileEntry);
  43. begin
  44.   FOutputStream := TMemoryStream.Create;
  45.   AStream := FOutputStream;
  46. end;
  47.  
  48. procedure TZipperClass.DoDoneOutZipStream(Sender: TObject; var AStream: TStream;
  49.   AItem: TFullZipFileEntry);
  50. begin
  51.   AStream.Position := 0;
  52.   FResultStream.CopyFrom(AStream, AStream.Size);
  53.   AStream.Free;
  54. end;
  55.  
  56. procedure TZipperClass.DoOpenInputStream(Sender: TObject; var AStream: TStream);
  57. begin
  58.   AStream := FInputStream;
  59. end;
  60.  
  61. function TZipperClass.Zip(const Input: TMemoryStream; Size: LongInt;
  62.   var Output: TMemoryStream; OutputReturn: Boolean): LongInt;
  63. begin
  64.  
  65. end;
  66.  
  67. function TZipperClass.UnZip(const Input: TMemoryStream; Size: LongInt;
  68.   var Output: TMemoryStream; OutputReturn: Boolean): LongInt;
  69. var
  70.   Unzipper: TUnZipper;
  71.   Bookmark: Int64;
  72. begin
  73.  
  74.   Result := 0;
  75.   Bookmark := Output.Position;
  76.  
  77.   FInputStream := TMemoryStream.Create;
  78.   FInputStream.CopyFrom(Input, Size);
  79.   FResultStream := TMemoryStream.Create;
  80.  
  81.   Unzipper := TUnZipper.Create;
  82.   with Unzipper do begin
  83.     OnCreateStream    := @DoCreateOutZipStream;
  84.     OnDoneStream      := @DoDoneOutZipStream;
  85.     OnOpenInputStream := @DoOpenInputStream;
  86.     try
  87.       UnZipAllFiles;
  88.     except
  89.     end;
  90.     Free;
  91.   end;
  92.  
  93.   FResultStream.Position := 0;
  94.   Output.CopyFrom(FResultStream, FResultStream.Size);
  95.   FResultStream.Free; // FInputStream & FOutputStream has already been freed
  96.  
  97.   Result := Output.Size - Bookmark;
  98.   if OutputReturn then Output.Position := Bookmark;
  99.  
  100. end;
  101.  
  102. function ZipData(const Input: TMemoryStream; Size: LongInt;
  103.   var Output: TMemoryStream; OutputReturn: Boolean): LongInt;
  104. var
  105.   Zipper: TZipperClass;
  106. begin
  107.   Zipper := TZipperClass.Create;
  108.   Result := Zipper.Unzip(Input, Size, Output, OutputReturn);
  109.   Zipper.Free;
  110. end;
  111.  
  112. function UnZipData(const Input: TMemoryStream; Size: LongInt;
  113.   var Output: TMemoryStream; OutputReturn: Boolean): LongInt;
  114. var
  115.   Zipper: TZipperClass;
  116. begin
  117.   Zipper := TZipperClass.Create;
  118.   Result := Zipper.Unzip(Input, Size, Output, OutputReturn);
  119.   Zipper.Free;
  120. end;
  121.  
  122. end.

Ove Halseth

  • Newbie
  • Posts: 6
Re: Unzip from a stream
« Reply #28 on: March 31, 2017, 10:26:08 am »
Thanks a lot:)

wps link to fpspreadsheet helped a lot.

And Handokos class will clean up my code:)


 

TinyPortal © 2005-2018