summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8f81564)
raw | patch | inline | side by side (parent: 8f81564)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Fri, 22 Apr 2016 12:19:13 +0000 (15:19 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Fri, 22 Apr 2016 12:19:29 +0000 (15:19 +0300) |
src/sfs/wadcvt.dpr | patch | blob | history |
diff --git a/src/sfs/wadcvt.dpr b/src/sfs/wadcvt.dpr
index 46dd0a772ef6ae2733c27398ea72a6cce1b96fa1..4885b327e10e3a45ba4e22ee0d72228b2a68319a 100644 (file)
--- a/src/sfs/wadcvt.dpr
+++ b/src/sfs/wadcvt.dpr
// returs crc
-function zpack (ds: TStream; ss: TStream): LongWord;
+function zpack (ds: TStream; ss: TStream; var aborted: Boolean): LongWord;
const
IBSize = 65536;
OBSize = 65536;
rd: Integer;
eof: Boolean;
crc: LongWord;
+ dstp, srcsize: Int64;
begin
result := 0;
+ //aborted := true; exit;
+ aborted := false;
crc := crc32(0, nil, 0);
GetMem(ib, IBSize);
GetMem(ob, OBSize);
ss.position := 0;
+ dstp := ds.position;
+ srcsize := ss.size;
try
zst.next_out := ob;
zst.avail_out := OBSize;
if zst.avail_out < OBSize then
begin
//writeln(' written ', OBSize-zst.avail_out, ' bytes');
+ if ds.position+(OBSize-zst.avail_out)-dstp >= srcsize then
+ begin
+ // this will be overwritten anyway
+ aborted := true;
+ exit;
+ end;
ds.writeBuffer(ob^, OBSize-zst.avail_out);
zst.next_out := ob;
zst.avail_out := OBSize;
if zst.avail_out < OBSize then
begin
//writeln(' .written ', OBSize-zst.avail_out, ' bytes');
+ if ds.position+(OBSize-zst.avail_out)-dstp >= srcsize then
+ begin
+ // this will be overwritten anyway
+ aborted := true;
+ exit;
+ end;
ds.writeBuffer(ob^, OBSize-zst.avail_out);
zst.next_out := ob;
zst.avail_out := OBSize;
const UtfFlags = (1 shl 10); // bit 11
{$ENDIF}
-function ZipOne (ds: TStream; fname: AnsiString; st: TStream): TFileInfo;
+function ZipOne (ds: TStream; fname: AnsiString; st: TStream; dopack: Boolean=true): TFileInfo;
var
- oldofs, nfoofs, pkdpos: Int64;
+ oldofs, nfoofs, pkdpos, rd: Int64;
sign: packed array [0..3] of Char;
+ buf: PChar;
+ bufsz: Integer;
+ aborted: Boolean = false;
{$IFDEF UTFEXTRA}
ef: TByteArray;
{$ENDIF}
result.pkofs := ds.position;
result.size := st.size;
if result.size > 0 then result.method := 8 else result.method := 0;
+ if not dopack then
+ begin
+ result.method := 0;
+ result.pksize := result.size;
+ end;
{$IFDEF UTFEXTRA}
result.name := fname;
ef := buildUtfExtra(result.name);
{$IFDEF UTFEXTRA}
if length(ef) > 0 then ds.writeBuffer(ef[0], length(ef));
{$ENDIF}
- // now write packed data
- if result.size > 0 then
+ if dopack then
+ begin
+ // now write packed data
+ if result.size > 0 then
+ begin
+ pkdpos := ds.position;
+ st.position := 0;
+ result.crc := zpack(ds, st, aborted);
+ result.pksize := ds.position-pkdpos;
+ if {result.pksize >= result.size} aborted then
+ begin
+ // there's no sence to pack this file, so just store it
+ st.position := 0;
+ ds.position := result.pkofs;
+ result.Free();
+ // store it
+ result := ZipOne(ds, fname, st, false);
+ exit;
+ end
+ else
+ begin
+ // fix header
+ oldofs := ds.position;
+ ds.position := nfoofs;
+ writeInt(ds, LongWord(result.crc)); // crc32
+ writeInt(ds, LongWord(result.pksize)); // crc32
+ ds.position := oldofs;
+ end;
+ end;
+ end
+ else
begin
- pkdpos := ds.position;
- st.position := 0;
- result.crc := zpack(ds, st);
- result.pksize := ds.position-pkdpos;
+ bufsz := 1024*1024;
+ GetMem(buf, bufsz);
+ try
+ st.position := 0;
+ result.crc := crc32(0, nil, 0);
+ result.pksize := 0;
+ while result.pksize < result.size do
+ begin
+ rd := result.size-result.pksize;
+ if rd > bufsz then rd := bufsz;
+ st.readBuffer(buf^, rd);
+ ds.writeBuffer(buf^, rd);
+ Inc(result.pksize, rd);
+ result.crc := crc32(result.crc, buf, rd);
+ end;
+ finally
+ FreeMem(buf);
+ end;
// fix header
oldofs := ds.position;
ds.position := nfoofs;
writeInt(ds, LongWord(result.crc)); // crc32
- writeInt(ds, LongWord(result.pksize)); // crc32
ds.position := oldofs;
+ write('(S) ');
end;
end;
//fs.Free();
//fs := SFSFileOpen(dvfn+'::'+fl[f].fPath+fl[f].fName);
fs.position := 0;
- writeln('[', f+1, '/', fl.Count, ']: ', fl[f].fPath, newname, ' ', fs.size);
+ write('[', f+1, '/', fl.Count, ']: ', fl[f].fPath, newname, ' ', fs.size, ' ... ');
nfo := ZipOne(fo, fl[f].fPath+newname, fs);
+ writeln('DONE');
SetLength(files, length(files)+1);
files[high(files)] := nfo;
end;