FORM v5.0.1-33-gdf7fc94
compress.c
Go to the documentation of this file.
1
7/* #[ License : */
8/*
9 * Copyright (C) 1984-2026 J.A.M. Vermaseren
10 * When using this file you are requested to refer to the publication
11 * J.A.M.Vermaseren "New features of FORM" math-ph/0010025
12 * This is considered a matter of courtesy as the development was paid
13 * for by FOM the Dutch physics granting agency and we would like to
14 * be able to track its scientific use to convince FOM of its value
15 * for the community.
16 *
17 * This file is part of FORM.
18 *
19 * FORM is free software: you can redistribute it and/or modify it under the
20 * terms of the GNU General Public License as published by the Free Software
21 * Foundation, either version 3 of the License, or (at your option) any later
22 * version.
23 *
24 * FORM is distributed in the hope that it will be useful, but WITHOUT ANY
25 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
26 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
27 * details.
28 *
29 * You should have received a copy of the GNU General Public License along
30 * with FORM. If not, see <http://www.gnu.org/licenses/>.
31 */
32/* #] License : */
33
34#include "form3.h"
35
36#ifdef WITHZLIB
37/*
38#define GZIPDEBUG
39
40 Low level routines for dealing with zlib during sorting and handling
41 the scratch files. Work started 5-sep-2005.
42 The .sor file handling was more or less completed on 8-sep-2005
43 The handling of the scratch files still needs some thinking.
44 Complications are:
45 gzip compression should be per expression, not per buffer.
46 No gzip compression for expressions with a bracket index.
47 Separate decompression buffers for expressions in the rhs.
48 This last one will involve more buffer work and organization.
49 Information about compression should be stored for each expr.
50 (including what method/program was used)
51 Note: Be careful with compression. By far the most compact method
52 is the original problem....
53
54 #[ Variables :
55
56 The following variables are to contain the intermediate buffers
57 for the inflation of the various patches in the sort file.
58 There can be up to MaxFpatches (FilePatches in the setup) and hence
59 we can have that many streams simultaneously. We set this up once
60 and only when needed.
61 (in struct A.N or AB[threadnum].N)
62 Bytef **AN.ziobufnum;
63 Bytef *AN.ziobuffers;
64*/
65
66/*
67 #] Variables :
68 #[ SetupOutputGZIP :
69
70 Routine prepares a gzip output stream for the given file.
71*/
72
73int SetupOutputGZIP(FILEHANDLE *f)
74{
75 GETIDENTITY
76
77 if ( AT.SS != AT.S0 ) return(0);
78 if ( AR.NoCompress == 1 ) return(0);
79 if ( AR.gzipCompress <= 0 ) return(0);
80
81 if ( f->ziobuffer == 0 ) {
82/*
83 1: Allocate a struct for the gzip stream:
84*/
85 f->zsp = Malloc1(sizeof(z_stream),"output zstream");
86/*
87 2: Allocate the output buffer.
88*/
89 f->ziobuffer =
90 (Bytef *)Malloc1(f->ziosize*sizeof(char),"output zbuffer");
91 if ( f->zsp == 0 || f->ziobuffer == 0 ) {
92 MLOCK(ErrorMessageLock);
93 MesCall("SetupOutputGZIP");
94 MUNLOCK(ErrorMessageLock);
95 Terminate(-1);
96 }
97 }
98/*
99 3: Set the default fields:
100*/
101 f->zsp->zalloc = Z_NULL;
102 f->zsp->zfree = Z_NULL;
103 f->zsp->opaque = Z_NULL;
104/*
105 4: Set the output space:
106*/
107 f->zsp->next_out = f->ziobuffer;
108 f->zsp->avail_out = f->ziosize;
109 f->zsp->total_out = 0;
110/*
111 5: Set the input space:
112*/
113 f->zsp->next_in = (Bytef *)(f->PObuffer);
114 f->zsp->avail_in = (Bytef *)(f->POfill) - (Bytef *)(f->PObuffer);
115 f->zsp->total_in = 0;
116/*
117 6: Initiate the deflation
118*/
119 if ( deflateInit(f->zsp,AR.gzipCompress) != Z_OK ) {
120/* INTERNAL_ERROR_EXCL_START */
121 MLOCK(ErrorMessageLock);
122 MesPrint("!>Error from zlib: %s",f->zsp->msg);
123 MesCall("SetupOutputGZIP");
124 MUNLOCK(ErrorMessageLock);
125 Terminate(-1);
126/* INTERNAL_ERROR_EXCL_STOP */
127 }
128
129 return(0);
130}
131
132/*
133 #] SetupOutputGZIP :
134 #[ PutOutputGZIP :
135
136 Routine is called when the PObuffer of f is full.
137 The contents of it will be compressed and whenever the output buffer
138 f->ziobuffer is full it will be written and the output buffer
139 will be reset.
140 Upon exit the input buffer will be cleared.
141*/
142
143int PutOutputGZIP(FILEHANDLE *f)
144{
145 GETIDENTITY
146 int zerror;
147/*
148 First set the number of bytes in the input
149*/
150 f->zsp->next_in = (Bytef *)(f->PObuffer);
151 f->zsp->avail_in = (Bytef *)(f->POfill) - (Bytef *)(f->PObuffer);
152 f->zsp->total_in = 0;
153
154 while ( ( zerror = deflate(f->zsp,Z_NO_FLUSH) ) == Z_OK ) {
155 if ( f->zsp->avail_out == 0 ) {
156/*
157 ziobuffer is full. Write the output.
158*/
159#ifdef GZIPDEBUG
160 {
161 char *s = (char *)((UBYTE *)(f->ziobuffer)+f->ziosize);
162 MLOCK(ErrorMessageLock);
163 MesPrint("%wWriting %l bytes at %10p: %d %d %d %d %d"
164 ,f->ziosize,&(f->POposition),s[-5],s[-4],s[-3],s[-2],s[-1]);
165 MUNLOCK(ErrorMessageLock);
166 }
167#endif
168#ifdef ALLLOCK
169 LOCK(f->pthreadslock);
170#endif
171 if ( f == AR.hidefile ) {
172 LOCK(AS.inputslock);
173 }
174 SeekFile(f->handle,&(f->POposition),SEEK_SET);
175 if ( WriteFile(f->handle,(UBYTE *)(f->ziobuffer),f->ziosize)
176 != f->ziosize ) {
177 if ( f == AR.hidefile ) {
178 UNLOCK(AS.inputslock);
179 }
180#ifdef ALLLOCK
181 UNLOCK(f->pthreadslock);
182#endif
183 MLOCK(ErrorMessageLock);
184 MesPrint("%wWrite error during compressed sort. Disk full?");
185 MUNLOCK(ErrorMessageLock);
186 return(-1);
187 }
188 if ( f == AR.hidefile ) {
189 UNLOCK(AS.inputslock);
190 }
191#ifdef ALLLOCK
192 UNLOCK(f->pthreadslock);
193#endif
194 ADDPOS(f->filesize,f->ziosize);
195 ADDPOS(f->POposition,f->ziosize);
196#ifdef WITHPTHREADS
197 if ( AS.MasterSort && AC.ThreadSortFileSynch ) {
198 if ( f->handle >= 0 ) SynchFile(f->handle);
199 }
200#endif
201/*
202 Reset the output
203*/
204 f->zsp->next_out = f->ziobuffer;
205 f->zsp->avail_out = f->ziosize;
206 f->zsp->total_out = 0;
207 }
208 else if ( f->zsp->avail_in == 0 ) {
209/*
210 We compressed everything and it sits in ziobuffer. Finish
211*/
212 return(0);
213 }
214 else {
215/* INTERNAL_ERROR_EXCL_START */
216 MLOCK(ErrorMessageLock);
217 MesPrint("!>%w avail_in = %d, avail_out = %d.",f->zsp->avail_in,f->zsp->avail_out);
218 MUNLOCK(ErrorMessageLock);
219 break;
220/* INTERNAL_ERROR_EXCL_STOP */
221 }
222 }
223/* INTERNAL_ERROR_EXCL_START */
224 MLOCK(ErrorMessageLock);
225 MesPrint("!>%wError in gzip handling of output. zerror = %d",zerror);
226 MUNLOCK(ErrorMessageLock);
227 return(-1);
228/* INTERNAL_ERROR_EXCL_STOP */
229}
230
231/*
232 #] PutOutputGZIP :
233 #[ FlushOutputGZIP :
234
235 Routine is called to flush a stream. The compression of the input buffer
236 will be completed and the contents of f->ziobuffer will be written.
237 Both buffers will be cleared.
238*/
239
240int FlushOutputGZIP(FILEHANDLE *f)
241{
242 GETIDENTITY
243 int zerror;
244/*
245 Set the proper parameters
246*/
247 f->zsp->next_in = (Bytef *)(f->PObuffer);
248 f->zsp->avail_in = (Bytef *)(f->POfill) - (Bytef *)(f->PObuffer);
249 f->zsp->total_in = 0;
250
251 while ( ( zerror = deflate(f->zsp,Z_FINISH) ) == Z_OK ) {
252 if ( f->zsp->avail_out == 0 ) {
253/*
254 Write the output
255*/
256#ifdef GZIPDEBUG
257 MLOCK(ErrorMessageLock);
258 MesPrint("%wWriting %l bytes at %10p",f->ziosize,&(f->POposition));
259 MUNLOCK(ErrorMessageLock);
260#endif
261#ifdef ALLLOCK
262 LOCK(f->pthreadslock);
263#endif
264 if ( f == AR.hidefile ) {
265 UNLOCK(AS.inputslock);
266 }
267 SeekFile(f->handle,&(f->POposition),SEEK_SET);
268 if ( WriteFile(f->handle,(UBYTE *)(f->ziobuffer),f->ziosize)
269 != f->ziosize ) {
270 if ( f == AR.hidefile ) {
271 UNLOCK(AS.inputslock);
272 }
273#ifdef ALLLOCK
274 UNLOCK(f->pthreadslock);
275#endif
276 MLOCK(ErrorMessageLock);
277 MesPrint("%wWrite error during compressed sort. Disk full?");
278 MUNLOCK(ErrorMessageLock);
279 return(-1);
280 }
281 if ( f == AR.hidefile ) {
282 UNLOCK(AS.inputslock);
283 }
284#ifdef ALLLOCK
285 UNLOCK(f->pthreadslock);
286#endif
287 ADDPOS(f->filesize,f->ziosize);
288 ADDPOS(f->POposition,f->ziosize);
289#ifdef WITHPTHREADS
290 if ( AS.MasterSort && AC.ThreadSortFileSynch ) {
291 if ( f->handle >= 0 ) SynchFile(f->handle);
292 }
293#endif
294/*
295 Reset the output
296*/
297 f->zsp->next_out = f->ziobuffer;
298 f->zsp->avail_out = f->ziosize;
299 f->zsp->total_out = 0;
300 }
301 }
302 if ( zerror == Z_STREAM_END ) {
303/*
304 Write the output
305*/
306#ifdef GZIPDEBUG
307 MLOCK(ErrorMessageLock);
308 MesPrint("%wWriting %l bytes at %10p",(LONG)(f->zsp->avail_out),&(f->POposition));
309 MUNLOCK(ErrorMessageLock);
310#endif
311#ifdef ALLLOCK
312 LOCK(f->pthreadslock);
313#endif
314 if ( f == AR.hidefile ) {
315 LOCK(AS.inputslock);
316 }
317 SeekFile(f->handle,&(f->POposition),SEEK_SET);
318 if ( WriteFile(f->handle,(UBYTE *)(f->ziobuffer),f->zsp->total_out)
319 != (LONG)(f->zsp->total_out) ) {
320 if ( f == AR.hidefile ) {
321 UNLOCK(AS.inputslock);
322 }
323#ifdef ALLLOCK
324 UNLOCK(f->pthreadslock);
325#endif
326 MLOCK(ErrorMessageLock);
327 MesPrint("%wWrite error during compressed sort. Disk full?");
328 MUNLOCK(ErrorMessageLock);
329 return(-1);
330 }
331 if ( f == AR.hidefile ) {
332 LOCK(AS.inputslock);
333 }
334#ifdef ALLLOCK
335 UNLOCK(f->pthreadslock);
336#endif
337 ADDPOS(f->filesize,f->zsp->total_out);
338 ADDPOS(f->POposition,f->zsp->total_out);
339#ifdef WITHPTHREADS
340 if ( AS.MasterSort && AC.ThreadSortFileSynch ) {
341 if ( f->handle >= 0 ) SynchFile(f->handle);
342 }
343#endif
344#ifdef GZIPDEBUG
345 MLOCK(ErrorMessageLock);
346 { char *s = f->ziobuffer+f->zsp->total_out;
347 MesPrint("%w Last bytes written: %d %d %d %d %d",s[-5],s[-4],s[-3],s[-2],s[-1]);
348 }
349 MesPrint("%w Perceived position in FlushOutputGZIP is %10p",&(f->POposition));
350 MUNLOCK(ErrorMessageLock);
351#endif
352/*
353 Reset the output
354*/
355 f->zsp->next_out = f->ziobuffer;
356 f->zsp->avail_out = f->ziosize;
357 f->zsp->total_out = 0;
358 if ( ( zerror = deflateEnd(f->zsp) ) == Z_OK ) return(0);
359/* INTERNAL_ERROR_EXCL_START */
360 MLOCK(ErrorMessageLock);
361 if ( f->zsp->msg ) {
362 MesPrint("!>%wError in finishing gzip handling of output: %s",f->zsp->msg);
363 }
364 else {
365 MesPrint("!>%wError in finishing gzip handling of output.");
366 }
367 MUNLOCK(ErrorMessageLock);
368 }
369 else {
370 MLOCK(ErrorMessageLock);
371 MesPrint("!>%wError in gzip handling of output.");
372 MUNLOCK(ErrorMessageLock);
373 }
374 return(-1);
375/* INTERNAL_ERROR_EXCL_STOP */
376}
377
378/*
379 #] FlushOutputGZIP :
380 #[ SetupAllInputGZIP :
381
382 Routine prepares all gzip input streams for a merge.
383
384 Problem (29-may-2008): If we never use GZIP compression, this routine
385 will still allocate the array space. This is an enormous amount!
386 It places an effective restriction on the value of SortIOsize
387*/
388
389int SetupAllInputGZIP(SORTING *S)
390{
391 GETIDENTITY
392 int i, NumberOpened = 0;
393 z_streamp zsp;
394/*
395 This code was added 29-may-2008 by JV to prevent further processing if
396 there is no compression at all (usually).
397*/
398 for ( i = 0; i < S->inNum; i++ ) {
399 if ( S->fpincompressed[i] ) break;
400 }
401 if ( i >= S->inNum ) return(0);
402
403 if ( S->zsparray == 0 ) {
404 S->zsparray = (z_streamp)Malloc1(sizeof(z_stream)*S->MaxFpatches,"input zstreams");
405 if ( S->zsparray == 0 ) {
406 MLOCK(ErrorMessageLock);
407 MesCall("SetupAllInputGZIP");
408 MUNLOCK(ErrorMessageLock);
409 Terminate(-1);
410 }
411/*
412 We add 128 bytes in the hope that if it can happen that it goes
413 outside the buffer during decompression, it does not do damage.
414*/
415 AN.ziobuffers = (Bytef *)Malloc1(S->MaxFpatches*(S->file.ziosize+128)*sizeof(Bytef),"input raw buffers");
416/*
417 This seems to be one of the really stupid errors:
418 We allocate way too much space. Way way way too much.
419 AN.ziobufnum = (Bytef **)Malloc1(S->MaxFpatches*S->file.ziosize*sizeof(Bytef *),"input raw pointers");
420*/
421 AN.ziobufnum = (Bytef **)Malloc1(S->MaxFpatches*sizeof(Bytef *),"input raw pointers");
422 if ( AN.ziobuffers == 0 || AN.ziobufnum == 0 ) {
423 MLOCK(ErrorMessageLock);
424 MesCall("SetupAllInputGZIP");
425 MUNLOCK(ErrorMessageLock);
426 Terminate(-1);
427 }
428 for ( i = 0 ; i < S->MaxFpatches; i++ ) {
429 AN.ziobufnum[i] = AN.ziobuffers + i * (S->file.ziosize+128);
430 }
431 }
432 for ( i = 0; i < S->inNum; i++ ) {
433#ifdef GZIPDEBUG
434 MLOCK(ErrorMessageLock);
435 MesPrint("%wPreparing z-stream %d with compression %d",i,S->fpincompressed[i]);
436 MUNLOCK(ErrorMessageLock);
437#endif
438 if ( S->fpincompressed[i] ) {
439 zsp = &(S->zsparray[i]);
440/*
441 1: Set the default fields:
442*/
443 zsp->zalloc = Z_NULL;
444 zsp->zfree = Z_NULL;
445 zsp->opaque = Z_NULL;
446/*
447 2: Set the output space:
448*/
449 zsp->next_out = Z_NULL;
450 zsp->avail_out = 0;
451 zsp->total_out = 0;
452/*
453 3: Set the input space temporarily:
454*/
455 zsp->next_in = Z_NULL;
456 zsp->avail_in = 0;
457 zsp->total_in = 0;
458/*
459 4: Initiate the inflation
460*/
461 if ( inflateInit(zsp) != Z_OK ) {
462/* INTERNAL_ERROR_EXCL_START */
463 MLOCK(ErrorMessageLock);
464 if ( zsp->msg ) MesPrint("!>%wError from inflateInit: %s",zsp->msg);
465 else MesPrint("!>%wError from inflateInit");
466 MesCall("SetupAllInputGZIP");
467 MUNLOCK(ErrorMessageLock);
468 Terminate(-1);
469/* INTERNAL_ERROR_EXCL_STOP */
470 }
471 NumberOpened++;
472 }
473 }
474 return(NumberOpened);
475}
476
477/*
478 #] SetupAllInputGZIP :
479 #[ FillInputGZIP :
480
481 Routine is called when we need new input in the specified buffer.
482 This buffer is used for the output and we keep reading and uncompressing
483 input till either this buffer is full or the input stream is finished.
484 The return value is the number of bytes in the buffer.
485*/
486
487LONG FillInputGZIP(FILEHANDLE *f, POSITION *position, UBYTE *buffer, LONG buffersize, int numstream)
488{
489 GETIDENTITY
490 int zerror;
491 LONG readsize, toread = 0;
492 SORTING *S = AT.SS;
493 z_streamp zsp;
494 POSITION pos;
495 if ( S->fpincompressed[numstream] ) {
496 zsp = &(S->zsparray[numstream]);
497 zsp->next_out = (Bytef *)buffer;
498 zsp->avail_out = buffersize;
499 zsp->total_out = 0;
500 if ( zsp->avail_in == 0 ) {
501/*
502 First loading of the input
503*/
504 if ( ISGEPOSINC(S->fPatchesStop[numstream],*position,f->ziosize) ) {
505 toread = f->ziosize;
506 }
507 else {
508 DIFPOS(pos,S->fPatchesStop[numstream],*position);
509 toread = (LONG)(BASEPOSITION(pos));
510 }
511 if ( toread > 0 ) {
512#ifdef GZIPDEBUG
513 MLOCK(ErrorMessageLock);
514 MesPrint("%w-+Reading %l bytes in stream %d at position %10p; stop at %10p",toread,numstream,position,&(S->fPatchesStop[numstream]));
515 MUNLOCK(ErrorMessageLock);
516#endif
517#ifdef ALLLOCK
518 LOCK(f->pthreadslock);
519#endif
520 SeekFile(f->handle,position,SEEK_SET);
521 readsize = ReadFile(f->handle,(UBYTE *)(AN.ziobufnum[numstream]),toread);
522 SeekFile(f->handle,position,SEEK_CUR);
523#ifdef ALLLOCK
524 UNLOCK(f->pthreadslock);
525#endif
526#ifdef GZIPDEBUG
527 MLOCK(ErrorMessageLock);
528 { char *s = AN.ziobufnum[numstream]+readsize;
529 MesPrint("%w read: %l +Last bytes read: %d %d %d %d %d in %s, newpos = %10p",readsize,s[-5],s[-4],s[-3],s[-2],s[-1],f->name,position);
530 }
531 MUNLOCK(ErrorMessageLock);
532#endif
533 if ( readsize == 0 ) {
534 zsp->next_in = AN.ziobufnum[numstream];
535 zsp->avail_in = f->ziosize;
536 zsp->total_in = 0;
537 return(zsp->total_out);
538 }
539 if ( readsize < 0 ) {
540/* INTERNAL_ERROR_EXCL_START */
541 MLOCK(ErrorMessageLock);
542 MesPrint("!>%wFillInputGZIP: Read error during compressed sort.");
543 MUNLOCK(ErrorMessageLock);
544 return(-1);
545/* INTERNAL_ERROR_EXCL_STOP */
546 }
547 ADDPOS(f->filesize,readsize);
548 ADDPOS(f->POposition,readsize);
549/*
550 Set the input
551*/
552 zsp->next_in = AN.ziobufnum[numstream];
553 zsp->avail_in = readsize;
554 zsp->total_in = 0;
555 }
556 }
557 if ( toread > 0 || zsp->avail_in ) {
558 while ( ( zerror = inflate(zsp,Z_NO_FLUSH) ) == Z_OK ) {
559 if ( zsp->avail_out == 0 ) {
560/*
561 Finish
562*/
563 return((LONG)(zsp->total_out));
564 }
565 if ( zsp->avail_in == 0 ) {
566
567 if ( ISEQUALPOS(S->fPatchesStop[numstream],*position) ) {
568/*
569 We finished this stream. Try to terminate.
570*/
571 zerror = Z_STREAM_END;
572 break;
573/*
574 if ( ( zerror = inflate(zsp,Z_SYNC_FLUSH) ) == Z_OK ) {
575 return((LONG)(zsp->total_out));
576 }
577 else
578 break;
579*/
580/*
581#ifdef GZIPDEBUG
582 MLOCK(ErrorMessageLock);
583 MesPrint("%wClosing stream %d",numstream);
584#endif
585 readsize = zsp->total_out;
586#ifdef GZIPDEBUG
587 if ( readsize > 0 ) {
588 WORD *s = (WORD *)(buffer+zsp->total_out);
589 MesPrint("%w Last words: %d %d %d %d %d",s[-5],s[-4],s[-3],s[-2],s[-1]);
590 }
591 else {
592 MesPrint("%w No words");
593 }
594 MUNLOCK(ErrorMessageLock);
595#endif
596 if ( ( zerror = inflateEnd(zsp) ) == Z_OK ) return(readsize);
597 break;
598*/
599 }
600/*
601 Read more input
602*/
603#ifdef GZIPDEBUG
604 if ( numstream == 0 ) {
605 MLOCK(ErrorMessageLock);
606 MesPrint("%wWant to read in stream 0 at position %10p",position);
607 MUNLOCK(ErrorMessageLock);
608 }
609#endif
610 if ( ISGEPOSINC(S->fPatchesStop[numstream],*position,f->ziosize) ) {
611 toread = f->ziosize;
612 }
613 else {
614 DIFPOS(pos,S->fPatchesStop[numstream],*position);
615 toread = (LONG)(BASEPOSITION(pos));
616 }
617#ifdef GZIPDEBUG
618 MLOCK(ErrorMessageLock);
619 MesPrint("%w--Reading %l bytes in stream %d at position %10p",toread,numstream,position);
620 MUNLOCK(ErrorMessageLock);
621#endif
622#ifdef ALLLOCK
623 LOCK(f->pthreadslock);
624#endif
625 SeekFile(f->handle,position,SEEK_SET);
626 readsize = ReadFile(f->handle,(UBYTE *)(AN.ziobufnum[numstream]),toread);
627 SeekFile(f->handle,position,SEEK_CUR);
628#ifdef ALLLOCK
629 UNLOCK(f->pthreadslock);
630#endif
631#ifdef GZIPDEBUG
632 MLOCK(ErrorMessageLock);
633 { char *s = AN.ziobufnum[numstream]+readsize;
634 MesPrint("%w Last bytes read: %d %d %d %d %d",s[-5],s[-4],s[-3],s[-2],s[-1]);
635 }
636 MUNLOCK(ErrorMessageLock);
637#endif
638 if ( readsize == 0 ) {
639 zsp->next_in = AN.ziobufnum[numstream];
640 zsp->avail_in = f->ziosize;
641 zsp->total_in = 0;
642 return(zsp->total_out);
643 }
644 if ( readsize < 0 ) {
645/* INTERNAL_ERROR_EXCL_START */
646 MLOCK(ErrorMessageLock);
647 MesPrint("!>%wFillInputGZIP: Read error during compressed sort.");
648 MUNLOCK(ErrorMessageLock);
649 return(-1);
650/* INTERNAL_ERROR_EXCL_STOP */
651 }
652 ADDPOS(f->filesize,readsize);
653 ADDPOS(f->POposition,readsize);
654/*
655 Reset the input
656*/
657 zsp->next_in = AN.ziobufnum[numstream];
658 zsp->avail_in = readsize;
659 zsp->total_in = 0;
660 }
661 else {
662 break;
663 }
664 }
665 }
666 else {
667 zerror = Z_STREAM_END;
668 zsp->total_out = 0;
669 }
670#ifdef GZIPDEBUG
671 MLOCK(ErrorMessageLock);
672 MesPrint("%w zerror = %d in stream %d. At position %10p",zerror,numstream,position);
673 MUNLOCK(ErrorMessageLock);
674#endif
675 if ( zerror == Z_STREAM_END ) {
676/*
677 Reset the input
678*/
679 zsp->next_in = Z_NULL;
680 zsp->avail_in = 0;
681 zsp->total_in = 0;
682/*
683 Make the final call and finish
684*/
685#ifdef GZIPDEBUG
686 MLOCK(ErrorMessageLock);
687 MesPrint("%wClosing stream %d",numstream);
688#endif
689 readsize = zsp->total_out;
690#ifdef GZIPDEBUG
691 if ( readsize > 0 ) {
692 WORD *s = (WORD *)(buffer+zsp->total_out);
693 MesPrint("%w -Last words: %d %d %d %d %d",s[-5],s[-4],s[-3],s[-2],s[-1]);
694 }
695 else {
696 MesPrint("%w No words");
697 }
698 MUNLOCK(ErrorMessageLock);
699#endif
700 if ( zsp->zalloc != Z_NULL ) {
701 zerror = inflateEnd(zsp);
702 zsp->zalloc = Z_NULL;
703 }
704 if ( zerror == Z_OK || zerror == Z_STREAM_END ) return(readsize);
705 }
706
707/* INTERNAL_ERROR_EXCL_START */
708 MLOCK(ErrorMessageLock);
709 MesPrint("!>%wFillInputGZIP: Error in gzip handling of input. zerror = %d",zerror);
710 MUNLOCK(ErrorMessageLock);
711 return(-1);
712/* INTERNAL_ERROR_EXCL_STOP */
713 }
714 else {
715#ifdef GZIPDEBUG
716 MLOCK(ErrorMessageLock);
717 MesPrint("%w++Reading %l bytes at position %10p",buffersize,position);
718 MUNLOCK(ErrorMessageLock);
719#endif
720#ifdef ALLLOCK
721 LOCK(f->pthreadslock);
722#endif
723 SeekFile(f->handle,position,SEEK_SET);
724 readsize = ReadFile(f->handle,buffer,buffersize);
725 SeekFile(f->handle,position,SEEK_CUR);
726#ifdef ALLLOCK
727 UNLOCK(f->pthreadslock);
728#endif
729 if ( readsize < 0 ) {
730/* INTERNAL_ERROR_EXCL_START */
731 MLOCK(ErrorMessageLock);
732 MesPrint("!>%wFillInputGZIP: Read error during uncompressed sort.");
733 MesPrint("%w++Reading %l bytes at position %10p",buffersize,position);
734 MUNLOCK(ErrorMessageLock);
735/* INTERNAL_ERROR_EXCL_STOP */
736 }
737 return(readsize);
738 }
739}
740
741/*
742 #] FillInputGZIP :
743 #[ ClearSortGZIP :
744*/
745
746void ClearSortGZIP(FILEHANDLE *f)
747{
748 if ( f->ziobuffer ) {
749 M_free(f->ziobuffer,"output zbuffer");
750 M_free(f->zsp,"output zstream");
751 f->ziobuffer = 0;
752 }
753}
754
755/*
756 #] ClearSortGZIP :
757*/
758#endif
int handle
Definition structs.h:709