[delphizip] Re: ZipBuilder DirEntry [Un]compressedSize mishmashed values in high DWORD

  • From: R Peters <rpeters@xxxxxxxxxxxxx>
  • To: delphizip@xxxxxxxxxxxxx
  • Date: Sat, 18 Sep 2010 09:35:18 +1000

Although initially I found similar after rebuilding it has consistently
given correct results (in B4).
Int Demo1::FillGrid there are some things that need updating for large zips
StringGrid1->RowCount = ZipBuilder1->Count + 2;
for(int i = 1; i <= ZipBuilder1->Count; i++)
  {
TZBDirEntry *zde = ZipBuilder1->DirEntry[i - 1];
/*unsigned*/ __int64 cs = zde->CompressedSize;
                /*unsigned*/ __int64 us = zde->UncompressedSize;
StringGrid1->Cells[0][i] = ExtractFileName( zde->FileName );
StringGrid1->Cells[1][i] = IntToStr( (__int64)cs );
StringGrid1->Cells[2][i] = IntToStr( (__int64)us );
StringGrid1->Cells[3][i] = FormatDateTime( "ddddd  t",
FileDateToDateTime(zde->DateTime));
// unsigned __int64 cs = zde->CompressedSize, us = zde->UncompressedSize;
if(us) StringGrid1->Cells[4][i] = IntToStr((__int64)(100 - cs * 100 / us -
((cs * 100 % us) >= us / 2))) + "% ";
else StringGrid1->Cells[4][i] = "0% ";
StringGrid1->Cells[5][i] = ExtractFilePath(zde->FileName);
    StringGrid1->Cells[6][i] = "N"; // means not selected
TotUncomp += us;
TotComp   += cs;
}
  SortGrid();

It is not surprising that it gave wrong results when it cast __int64 to int
- my test did not do it that way so that was not why initially I saw wrong
values or why rebuilding cured it (B4 had many problems which is a lot of
the reason that although I prefer C++ I changed to Delphi where at least I
did not have to fight the compiler).

Do you have all BCB 4 updates installed?
Russell Peters

2010/9/18 Roger Aelbrecht <Roger.Aelbrecht@xxxxxxxxx>

> Lubomir Prochazka wrote:
> >
> >
> > Roger Aelbrecht napsal(a):
> >> Lubomir Prochazka wrote:
> >>>
> >>> Roger Aelbrecht napsal(a):
> >>>> Lubomir Prochazka wrote:
> >>>>> Hello,
> >>>>>
> >>>>> I have built up these files:
> >>>>> name            size           size hex
> >>>>> 1g1random1.bin  1 073 741 825  0x40000001
> >>>>> 1g1random2.bin  1 073 741 825  0x40000001
> >>>>> 1g1random3.bin  1 073 741 825  0x40000001
> >>>>> 1g1random4.bin  1 073 741 825  0x40000001
> >>>>> 1g1random5.bin  1 073 741 825  0x40000001
> >>>>> 1g1zeroes.bin   1 073 741 825  0x40000001
> >>>>> 4g1zeroes.bin   4 294 967 297  0x100000001
> >>>>>
> >>>>>
> >>>>> Compressed by WinZip ver 14.5:
> >>>>> name            size           packed size
> >>>>> 1g1random1.bin  1 073 741 825  1 073 905 995
> >>>>> 1g1random2.bin  1 073 741 825  1 073 905 995
> >>>>> 1g1random3.bin  1 073 741 825  1 073 905 995
> >>>>> 1g1random4.bin  1 073 741 825  1 073 905 995
> >>>>> 1g1random5.bin  1 073 741 825  1 073 905 995
> >>>>> 1g1zeroes.bin   1 073 741 825      1 042 051
> >>>>> 4g1zeroes.bin   4 294 967 297      4 168 157
> >>>>>
> >>>>>
> >>>>>
> >>>>> This testing source code:
> >>>>>
> >>>>> void __fastcall TForm1::Button1Click(TObject *Sender)
> >>>>> {
> >>>>>       if (OpenDialog1->Execute() == false)
> >>>>>         return;
> >>>>>
> >>>>>       Memo1->Clear();
> >>>>>       ZipBuilder1->ZipFileName = OpenDialog1->FileName;
> >>>>>       for(int i = 0; i<    ZipBuilder1->Count; i++)
> >>>>>       {
> >>>>>         Memo1->Lines->Add(ZipBuilder1->DirEntry[i]->FileName
> >>>>>           + " / 0x" +
> IntToHex(ZipBuilder1->DirEntry[i]->UncompressedSize, 16)
> >>>>>           + " / 0x" +
> IntToHex(ZipBuilder1->DirEntry[i]->CompressedSize, 16));
> >>>>>       }
> >>>>>       __int64 test64 = 65536; test64 *= test64;
> >>>>>       Memo1->Lines->Add("0x" + IntToHex(++test64, 16));
> >>>>> }
> >>>>>
> >>>>>
> >>>>>
> >>>>> Produces this output:
> >>>>> 1g1random1.bin / 0x9C895440000001 / 0x9C89544002814B
> >>>>> 1g1random2.bin / 0x9C9A2040000001 / 0x9C9A204002814B
> >>>>> 1g1random3.bin / 0x9C9B2C40000001 / 0x9C9B2C4002814B
> >>>>> 1g1random4.bin / 0x9C9C3840000001 / 0x9C9C384002814B
> >>>>> 1g1random5.bin / 0x9C9D4440000001 / 0x9C9D444002814B
> >>>>> 1g1zeroes.bin / 0x9C9E6840000001 / 0x9C9E68000FE683
> >>>>> 4g1zeroes.bin / 0x9C9F8C00000001 / 0x9C9F8C003F99DD
> >>>>> 0x100000001
> >>>>>
> >>>>>
> >>>>>
> >>>>> I try it in BCB4 (not havin' BCB5)
> >>>>>
> >>>>> kind regards
> >>>>> Lubosh
> >>>>>
> >>>> I repeated your test on BCB5, with some of own zip files and all
> output
> >>>> was correct, I don't have BCB4 so I cannot try.
> >>>> Are you sure that BCB5 has the correct version of IntToHex
> >>>> I have a copy of the DString.h file from BCB4 and I can find
> >>>> static AnsiString __fastcall IntToHex(int value, int digits);
> >>>>
> >>>> But in this case we need:
> >>>> static AnsiString __fastcall IntToHex(__int64 value, int digits);
> >>>>
> >>>>
> >>>>
> >>> Hello,
> >>> thanks for checkin'on the test of the BCB5. There are these
> declarations
> >>> in header file sysutils.hpp at BCB4:
> >>> extern PACKAGE AnsiString __fastcall IntToHex(int Value, int
> >>> Digits)/* overload */;
> >>> extern PACKAGE AnsiString __fastcall IntToHex(__int64 Value,
> >>> int Digits)/* overload */;
> >>>
> >>> So that the code:
> >>> Memo1->Lines->Add("0x" + IntToHex(++test64, 16));
> >>> extract correctly:
> >>> 0x100000001
> >>>
> >>> It seems like my BCB4 do something wrong durin' the compilation of
> >>> source codes of the ZipBuilder. It somewhere does not take over the
> >>> upper 32bits and leave there a kind of trash.
> >>>
> >>>
> >>> Sincerely
> >>> Lubosh
> >>> -----------
> >>> To unsubscribe from this list, send an empty e-mail
> >>> message to:
> >>>     delphizip-request@xxxxxxxxxxxxx
> >>> and put the word unsubscribe in the subject.
> >>>
> >>>
> >>
> >> Is the above an exact copy of what you see in the memo?
> >> If yes then there is something strange, you specified 16 digits and the
> >> leading '0's are not showing.
> >> BCB5 show the folowing format
> >>
> >> META-INF\manifest.xml / 0x0000000000000828 / 0x0000000000000165
> >> 0x0000000100000001
> >>
> >
> > Hello,
> >
> > you are right, in a number of the written out digits is a bug, but the
> > very value is all right. I've made a test with this resolution:
> >
> > for (int i = 1; i<= 17; i++)
> >     Memo1->Lines->Add("0x" + IntToHex(1, i));
> >
> > Memo1->Lines->Add("0x" + IntToHex(8526495043095935640i64, 0));
> >
> > 0x1
> > 0x01
> > 0x001
> > 0x0001
> > 0x00001
> > 0x000001
> > 0x0000001
> > 0x00000001
> > 0x000000001
> > 0x0000000001
> > 0x00000000001
> > 0x000000000001
> > 0x0000000000001
> > 0x00000000000001
> > 0x000000000000001
> > 0x1
> > 0x1
> > 0x76543210FEDCBA98
> >
> >
> > Nevertheless, there's mishmash in the variable CompressedSize and
> > UncompressedSize at upper 32bits. I suppose that BCB4 in the source code
> > of ZipBuilder is not able to catch on the point that take over the size
> > of a header of ZIP file. To find out the point it could be rewritten for
> > sure so that the code is compatible with BCB4.
> > I hope I'm not the last user of BCB4.
> > And what about the Delphi4, is it able to compile it well?
> >
> >
> > --
> > Lubosh
> > -----------
> > To unsubscribe from this list, send an empty e-mail
> > message to:
> >    delphizip-request@xxxxxxxxxxxxx
> > and put the word unsubscribe in the subject.
> >
> >
> I am not suer what you mean with :
> "To find out the point it could be rewritten for
>  sure so that the code is compatible with BCB4."
> The code in ZipBuilder is reading the header of the ZipFile in a
> structure TZipCentralHeader
> with declarations
>        unsigned long   ComprSize;          //compressed file size  (4)
>        unsigned long   UnComprSize;        //uncompressed file size (4)
>
> Then the read values are copied to correspionding properties in the
> ZBIRec class declared as
> __property __int64 CompressedSize={read=FComprSize,write=FComprSize};
> and
> __int64 FComprSize;  //compressed file size  (8)
>
> This is done in the function
> int __fastcall TZBIRec::Read(TZBZipFile* wf)
>
> There is no special code involved in the conversion to __int64, all is
> internal in the compiler.
>
> to make sure that the upper bits are zeroed before the conversion you
> could try:
>
> Add two lines in TZBIRec::Read
> just before
>  CompressedSize = CH.ComprSize;
> Add the lines
>
> CompressedSize = 0i64;
> UncompressedSize = 0i64;
>
> If that doesn't help we could try setting the bits in code and replace
> these 2 lines by
> memset(&FComprSize, 0, sizeof(__int64));
> memset(&FUnComprSize, 0, sizeof(__int64));
>
> If one of the above helps we can add that to code with compiler
> directive for BCB4
>
>
> --
> Roger Aelbrecht
>
> -----------
> To unsubscribe from this list, send an empty e-mail
> message to:
>  delphizip-request@xxxxxxxxxxxxx
> and put the word unsubscribe in the subject.
>


-----------
To unsubscribe from this list, send an empty e-mail 
message to:
  delphizip-request@xxxxxxxxxxxxx 
and put the word unsubscribe in the subject.

Other related posts: