delphi - EZDecompressionError using TStreamReader with TZDecompressionStream -


i have program works fine in xe2 fails in xe6. tracing problem isn't difficult. create tzdecompressionstream using built in zip handling classes , submit tstreamreader. code intended support plain uncompressed files , compressed files , hence reader pointed @ "filestream" variable either tfilestream (which works) or tzdecompressionstream (which exhibits fault)

reader := tstreamreader.create(filestream, tencoding.ascii); 

the problem tstreamreader, when reads data, calls internal routine adjustendofbuffer attempts make sure buffer contains complete characters. unfortunately has following line rewinds stream if necessary invoked whther there need rewind or not

fstream.position := fstream.position - rewind; 

where in case rewind has value of 0 , tzdecompressionstream takes exception this. fault in tzdecompressionstream in seek current position should evaluated ok since no-op. actual seek expressed in tstreamreader move current offset relative beginning of stream.

the actual code in tzdecompressionstream.seek allows return start (ie rewind stream), move forward past current position , move end not allow move give current position. following code adjudicates permission move forward

(((nativeuint(offset) - fzstream.total_out) > 0) , (origin = sobeginning)) 

but should have >= below

(((nativeuint(offset) - fzstream.total_out) >= 0) , (origin = sobeginning)) 

does know way around fault without abandoning tstreamreader? there way modify behaviour of tzdecompressionstream has been created tzipfile class?

i've come own answer avoids messing vcl source code. isn't nice thing brief , avoids confusion other parts of system. i've implemented class tsptzdecompressionstream overrides faulty seek , no-ops move zero. have class function convert replaces vmt pointer in tzdecompressionstream vmt pointer new class. should safe classes identical in respects except overridden method. else experiencing same problem should able use code , call

tsptzdecompressionstream.convert(stream tzdecompressionstream); 

to trigger conversion

declaration

type   tsptzdecompressionstream = class(tzdecompressionstream)     class procedure convert(decompressionstream: tzdecompressionstream);     function seek(const offset: int64; origin: tseekorigin): int64; override;   end; 

implementation

{ tsptzdecompressionstream }  class procedure tsptzdecompressionstream.convert(decompressionstream: tzdecompressionstream); begin   // switch vmt pointer point tsptzdecompressionstream vmt   ppointer(decompressionstream)^ := ppointer(tsptzdecompressionstream); end;  function tsptzdecompressionstream.seek(const offset: int64; origin: tseekorigin): int64; begin   if (origin = sobeginning) , (offset = position)   begin     result := offset;     exit;   end   else   begin     result := inherited seek(offset, origin);   end; end; 

i can't think of reason why particularly bad idea other usual issue of hacking internal data formats welcome further comments.

note implementation 64bit seek version implemented tzdecompressionstream. delphi directs streams should implement either 32bit version (old seek method signature) or 64bit version. bear in mind code not function in conjunction version of tzdecompressionstream implements 32bit seek (i don't know if dates far enough have ever been case)


Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -