/* s4next.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */ #include "d4all.h" #ifndef S4UNIX #ifdef __TURBOC__ #pragma hdrstop #endif #endif int s4nextSpoolEntry( SORT4 *s4 ) { long lastDiskPos, diskDataLeft, newRec, spoolRec ; unsigned maxRead, lenRead ; int low, high, pos, rc ; char *newData ; S4SPOOL saveSpool ; #ifdef E4PARM_LOW if ( s4 == 0 ) return error4( 0, e4parm_null, E91908 ) ; #endif s4->spoolPointer->pos += s4->totLen ; if ( s4->spoolPointer->pos >= s4->spoolPointer->len ) { s4->spoolPointer->pos = 0 ; if ( s4->spoolPointer->disk >= 0L ) { lastDiskPos = (s4->spoolPointer->spoolI+1) * s4->spoolDiskLen ; diskDataLeft = lastDiskPos - s4->spoolPointer->disk ; maxRead = s4->spoolMemLen ; if ( (long) s4->spoolMemLen > diskDataLeft ) maxRead = (unsigned) diskDataLeft ; lenRead = file4read( &s4->file, s4->spoolPointer->disk, s4->spoolPointer->ptr, maxRead) ; if ( error4code( s4->codeBase ) < 0 ) { sort4free( s4 ) ; return error4stack( s4->codeBase, (short)error4code( s4->codeBase ), E91908 ) ; } s4->spoolPointer->len = lenRead ; s4->spoolPointer->disk += lenRead ; if ( lenRead != maxRead || lenRead == 0 ) { if ( lenRead % s4->totLen ) { sort4free( s4 ) ; return error4describe( s4->codeBase, e4read, E91908, s4->file.name, 0, 0 ) ; } s4->spoolPointer->disk = -1 ; if ( lenRead == 0 ) { s4deleteSpoolEntry( s4 ) ; return 0 ; } else s4->spoolPointer->len = lenRead ; } else /* Check if we are out of disk entries for the spool */ if ( s4->spoolPointer->disk >= lastDiskPos ) s4->spoolPointer->disk = -1L ; } else { s4deleteSpoolEntry(s4) ; return 0 ; } } /* Position the new entry to the sorted location using a binary search */ /* New entry is placed before 'result': int pos >= 1 when complete */ low = 1 ; high = s4->spoolsN ; newData = s4->spoolPointer->ptr + s4->spoolPointer->pos ; memcpy( (void *)&newRec, newData + s4->sortLen, sizeof(newRec) ) ; for(;;) { pos = ( low + high ) / 2 ; if ( pos == low && pos == high ) /* then found */ { memcpy( (void *)&saveSpool, (void *)s4->spoolPointer, sizeof(S4SPOOL) ) ; c4memmove( s4->spoolPointer, s4->spoolPointer+1, sizeof(S4SPOOL)*(pos-1) ) ; memcpy( (void *)(s4->spoolPointer+pos-1), (void *)&saveSpool, sizeof(S4SPOOL) ) ; return 0 ; } rc = (*s4->cmp)(newData, s4->spoolPointer[pos].ptr + s4->spoolPointer[pos].pos, s4->sortLen) ; if ( rc == 0 ) { memcpy( (void *)&spoolRec, s4->spoolPointer[pos].ptr + s4->spoolPointer[pos].pos + s4->sortLen, sizeof(spoolRec) ) ; if ( newRec > spoolRec ) rc = 1 ; } if ( rc > 0 ) low = pos+1 ; else high = pos ; #ifdef E4ANALYZE if ( high < low ) return error4( s4->codeBase, e4result, E91908 ) ; #endif } }