campo-sirio/cb/source/m4memo.c

433 lines
11 KiB
C
Raw Normal View History

/* m4memo.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
#include "d4all.h"
#ifndef S4UNIX
#ifdef __TURBOC__
#pragma hdrstop
#endif
#endif
#ifndef S4OFF_MEMO
#ifdef S4CLIENT
#ifndef S4OFF_WRITE
int S4FUNCTION d4memoCompress( DATA4 *data )
{
int rc ;
CONNECTION4 *connection ;
CODE4 *c4 ;
#ifdef S4VBASIC
if ( c4parm_check( data, 2, E95201 ) )
return -1 ;
#endif
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E95201 ) ;
#endif
c4 = data->codeBase ;
if ( error4code( c4 ) < 0 )
return e4codeBase ;
if ( data->readOnly == 1 )
return error4describe( c4, e4write, E80606, d4alias( data ), 0, 0 ) ;
if ( data->dataFile->nFieldsMemo == 0 )
return 0 ;
rc = d4update( data ) ;
if ( rc )
return rc ;
connection = data->dataFile->connection ;
if ( connection == 0 )
return error4stack( c4, e4connection, E95201 ) ;
data->count = -1 ;
data->dataFile->numRecs = -1 ;
connection4assign( connection, CON4MEMO_COMPRESS, data4clientId( data ), data4serverId( data ) ) ;
rc = connection4repeat( connection, -2, -1, -1, data ) ;
if ( rc < 0 )
connection4error( connection, c4, rc, E95201 ) ;
return rc ;
}
#endif /* S4OFF_WRITE */
#endif /* S4CLIENT */
#endif /* S4OFF_MEMO */
#ifndef S4CLIENT
#ifndef S4OFF_MEMO
#ifdef S4MFOX
long memo4lenPart( MEMO4FILE *f4memo, long memoId )
{
long pos ;
int rc ;
MEMO4BLOCK memoBlock ;
if ( memoId <= 0L )
return 0 ;
pos = memoId * f4memo->blockSize ;
rc = file4readAll( &f4memo->file, pos, &memoBlock, sizeof( MEMO4BLOCK ) ) ;
if ( rc < 0 )
return error4stack( f4memo->file.codeBase, rc, E95204 ) ;
#ifdef S4BYTE_SWAP
memoBlock.type = x4reverseLong( (void *)&memoBlock.type ) ;
memoBlock.numChars = x4reverseLong( (void *)&memoBlock.numChars ) ;
#endif
return x4reverseLong( (void *)&memoBlock.numChars ) ;
}
#endif
#ifndef S4OFF_WRITE
int S4FUNCTION d4memoCompress( DATA4 *data )
{
CODE4 *c4 ;
int rc ;
#ifdef S4VBASIC
if ( c4parm_check( data, 2, E95201 ) )
return -1 ;
#endif
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E95201 ) ;
#endif
c4 = data->codeBase ;
if ( error4code( c4 ) < 0 )
return e4codeBase ;
if ( data->dataFile->nFieldsMemo == 0 )
return 0 ;
rc = d4update( data ) ;
if ( rc )
return rc ;
#ifndef S4OFF_MULTI
#ifdef S4SERVER
rc = dfile4lockFile( data->dataFile, data4clientId( data ), data4serverId( data ) ) ;
#else
rc = d4lockFile( data ) ;
#endif
if ( rc )
return rc ;
#endif
#ifndef S4OFF_TRAN
if ( code4transEnabled( c4 ) )
if ( tran4active( c4, data ) != 0 )
return error4( c4, e4transViolation, E81502 ) ;
#endif
return dfile4memoCompress( data->dataFile, data ) ;
}
int dfile4memoCompress( DATA4FILE *data, DATA4 *d4 )
{
char *rdBuf, *wrBuf, *ptr ;
FILE4SEQ_READ rd ;
FILE4SEQ_WRITE wr ;
MEMO4FILE newFile ;
CODE4 *c4 ;
unsigned int bufSize, ptrLen, ptrMax, saveFlag ;
long curCount, iRec, newId ;
int rc, i ;
FIELD4 *field ;
#ifdef S4MFOX
long memoLen, memoType ;
unsigned long pos ;
memoType = 1 ;
#endif
#ifdef S4VBASIC
if ( c4parm_check( d4, 2, E95201 ) )
return -1 ;
#endif
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E95201 ) ;
#endif
c4 = data->c4 ;
if ( error4code( c4 ) < 0 )
return e4codeBase ;
if ( data->memoFile.file.hand == -1 )
return 0 ;
#ifndef S4OFF_MULTI
#ifndef N4OTHER
#ifdef S4SERVER
rc = dfile4lockMemo( data ) ;
#else
rc = dfile4lockMemo( data ) ;
#endif
if ( rc )
return rc ;
#endif
#endif
saveFlag = c4->memSizeMemo ;
c4->memSizeMemo = (unsigned int)data->memoFile.blockSize ;
rc = memo4fileCreate( &newFile, c4, data, 0 ) ;
if ( rc < 0 )
return error4stack( c4, rc, E91102 ) ;
c4->memSizeMemo = saveFlag ;
newFile.blockSize = data->memoFile.blockSize ;
rdBuf = wrBuf = 0 ;
bufSize = c4->memSizeBuffer ;
for (; bufSize > data->recWidth; bufSize -= 0x800 )
{
rdBuf = (char *)u4allocFree( c4, (long)bufSize ) ;
if ( rdBuf == 0 )
continue ;
wrBuf = (char *)u4allocFree( c4, (long)bufSize ) ;
if ( wrBuf )
break ;
u4free( rdBuf ) ;
rdBuf = 0 ;
}
#ifdef S4ADVANCE_READ
file4seqReadInitDo( &rd, &data->file, dfile4recordPosition( data, 1L ), rdBuf, bufSize, 1 ) ;
#else
file4seqReadInit( &rd, &data->file, dfile4recordPosition( data, 1L ), rdBuf, bufSize ) ;
#endif
file4seqWriteInit( &wr, &data->file, dfile4recordPosition( data, 1L ), wrBuf, bufSize ) ;
curCount = dfile4recCount( data, data4serverId( d4 ) ) ;
ptr = 0 ;
ptrLen = ptrMax = 0 ;
for ( iRec= 1L ; iRec <= curCount && rc == 0 ; iRec++ )
{
if ( file4seqReadAll( &rd, d4->record, data->recWidth ) < 0 )
break ;
for ( i = 0 ; i < d4->dataFile->nFieldsMemo ; i++ )
{
field = d4->fieldsMemo[i].field ;
#ifdef S4FOX
pos = 0L ;
if ( f4null( field ) == 1 )
memoLen = 0 ;
else
memoLen = memo4lenPart( &data->memoFile, f4long( field ) ) ;
if ( memoLen > 0L )
{
newId = 0L ;
do
{
#ifdef E4ANALYZE
if ( pos > (unsigned long)memoLen )
{
rc = error4( c4, e4memoCorrupt, E91102 ) ;
break ;
}
#endif
ptrLen = ptrMax ;
if ( memo4fileReadPart( &data->memoFile, f4long( field ), &ptr, &ptrLen, pos, UINT_MAX - 100, &memoType ) < 0 )
{
rc = -1 ;
break ;
}
if ( ptrLen > ptrMax )
ptrMax = ptrLen ;
if ( memo4fileWritePart( &newFile, &newId, ptr, memoLen, pos, ptrLen, memoType ) < 0 )
{
rc = -1 ;
break ;
}
pos += ptrLen ;
} while( pos != (unsigned long)memoLen ) ;
c4ltoa45( newId, f4ptr(field), -( (int)field->len ) ) ;
}
else
c4ltoa45( 0L, f4ptr(field), -( (int)field->len) ) ;
#else
ptrLen = ptrMax ;
if ( memo4fileRead( &data->memoFile, f4long(field), &ptr, &ptrLen ) < 0 )
{
rc = -1 ;
break ;
}
if ( ptrLen > ptrMax )
ptrMax = ptrLen ;
newId = 0L ;
if ( memo4fileWrite( &newFile, &newId, ptr, ptrLen ) < 0 )
{
rc = -1 ;
break ;
}
c4ltoa45( newId, f4ptr(field), - ((int) field->len) ) ;
#endif
}
file4seqWrite( &wr, d4->record, data->recWidth ) ;
}
if ( rc < 0 )
file4close( &newFile.file ) ; /* error occurred */
else
file4seqWriteFlush(&wr) ;
#ifdef S4ADVANCE_READ
file4seqReadInitUndo( &rd ) ;
#endif
u4free( ptr ) ;
u4free( rdBuf ) ;
u4free( wrBuf ) ;
if ( rc == 0 )
{
rc = file4replace( &data->memoFile.file, &newFile.file ) ;
if ( rc == 0 )
#ifdef S4MMDX
if ( file4len( &data->memoFile.file ) < data->memoFile.blockSize )
rc = file4lenSet( &data->memoFile.file, data->memoFile.blockSize ) ;
#else
if ( file4len( &data->memoFile.file ) < 512 )
rc = file4lenSet( &data->memoFile.file, 512L ) ;
#endif
}
return rc ;
}
#endif /* S4OFF_WRITE */
#ifndef S4MFOX
#ifndef S4MNDX
int memo4fileChainFlush( MEMO4FILE *f4memo, MEMO4CHAIN_ENTRY *chain )
{
#ifdef S4BYTE_SWAP
MEMO4CHAIN_ENTRY swap ;
#endif
if ( chain->toDisk )
{
chain->toDisk = 0 ;
#ifdef S4BYTE_SWAP
memcpy( (void *)&swap, (void *)chain, sizeof( MEMO4CHAIN_ENTRY ) ) ;
swap.next = x4reverseLong( (void *)&swap.next ) ;
swap.num = x4reverseLong( (void *)&swap.num ) ;
return file4write( &f4memo->file, chain->blockNo * f4memo->blockSize, &swap, 2*sizeof(S4LONG) ) ;
#else
return file4write( &f4memo->file, chain->blockNo * f4memo->blockSize, chain, 2*sizeof(S4LONG) ) ;
#endif
}
return 0 ;
}
int memo4fileChainSkip( MEMO4FILE *f4memo, MEMO4CHAIN_ENTRY *chain )
{
unsigned lenRead ;
chain->toDisk = 0 ;
chain->blockNo = chain->next ;
if ( chain->next < 0 )
lenRead = 0 ;
else
{
lenRead = file4read( &f4memo->file, chain->next * f4memo->blockSize, chain, sizeof(chain->next)+sizeof(chain->num) ) ;
#ifdef S4BYTE_SWAP
chain->next = x4reverseLong( (void *)&chain->next ) ;
chain->num = x4reverseLong( (void *)&chain->num ) ;
#endif
}
if ( f4memo->data->c4->errorCode < 0 )
return -1 ;
if ( lenRead == 0 )
{
chain->num = -1 ;
chain->next = -1 ;
return 0 ;
}
if ( lenRead != sizeof(chain->next)+sizeof(chain->num) )
return file4readError( &f4memo->file, chain->next * f4memo->blockSize, sizeof(chain->next)+sizeof(chain->num), "memo4fileChainSkip" ) ;
return 0 ;
}
#endif
#endif
#endif /* S4OFF_MEMO */
/* Make the memo file entries current */
#ifndef S4OFF_MEMO
#ifndef S4OFF_MULTI
int d4validateMemoIds( DATA4 *data )
{
int i, rc ;
char *fromPtr ;
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E95203 ) ;
#endif
if ( data->memoValidated )
return 0 ;
if ( data->recNum > 0 )
{
#ifdef S4SERVER
rc = dfile4lock( data->dataFile, data4clientId( data ), data4serverId( data ), data->recNum ) ;
#else
rc = d4lock( data, data->recNum ) ;
#endif
if ( rc )
return rc ;
}
rc = d4readOld( data, data->recNum ) ;
if ( rc < 0 )
return error4stack( data->codeBase, rc, E95203 ) ;
if ( data->recordChanged == 0 ) /* if the record has changed, leave intact */
for ( i = 0 ; i < data->dataFile->nFieldsMemo ; i++ )
{
if ( data->fieldsMemo[i].isChanged == 0 )
{
fromPtr = data->recordOld + data->fieldsMemo[i].field->offset ;
memcpy( f4ptr( data->fieldsMemo[i].field ), fromPtr, f4len( data->fieldsMemo[i].field ) ) ; /* need f4len() because S4FOX 3.0 has 4 byte memos, not 10 byte */
}
}
data->memoValidated = 1 ;
return 0 ;
}
#endif /* S4OFF_MULTI */
#endif /* S4OFF_MEMO */
#endif /* S4CLIENT */