/* d4extra.c   (c)Copyright Sequiter Software Inc., 1988-1996.  All rights reserved. */

#include "d4all.h"

#ifndef UNIX
   #ifdef __TURBOC__
      #pragma hdrstop
   #endif
#endif

#ifdef E4ANALYZE
#ifdef P4ARGS_USED
   #pragma argsused
#endif
int code4verify( CODE4 *c4, int subs )
{
   if ( c4 == 0 )
      return error4( 0, e4parm_null, E93901 ) ;

   if ( error4code( c4 ) < 0 )
      return error4code( c4 ) ;

   return 0 ;
}

int dfile4verify( DATA4FILE *d4, int subs )
{
   int rc ;

   if ( d4 == 0 )
      return error4( 0, e4parm_null, E91102 ) ;

   if ( d4->c4 == 0 )
      return error4( 0, e4struct, E91102 ) ;

   if ( subs == 1 )
      if ( ( rc = code4verify( d4->c4, 1 ) ) < 0 )
         return rc ;

   return 0 ;
}

#ifndef S4SINGLE
#ifndef S4CLIENT
int lock4verify( LOCK4 *lock, const int subs )
{
   int rc ;

   if ( lock->data == 0 )
      return error4( 0, e4parm_null, E93903 ) ;

   if ( subs == 1 )
      if ( ( rc = dfile4verify( lock->data, 1 ) ) < 0 )
         return rc ;

   if ( lock->link.n == 0 || lock->link.p == 0 )
      return error4( lock->data->c4, e4struct, E93903 ) ;

   return 0 ;
}
#endif  /* S4CLIENT */
#endif  /* S4SINGLE */
#endif  /* E4ANALYZE */

#ifndef S4SINGLE
#ifndef S4CLIENT
int lock4lock( LOCK4 *lock )
{
   int rc ;

#ifdef E4ANALYZE
   if ( ( rc = lock4verify( lock, 1 ) ) < 0 )
      return rc ;
#endif

   switch( lock->id.type )
   {
      case LOCK4ALL:
         rc = dfile4lockAll( lock->data, lock->id.clientId, lock->id.serverId ) ;
         break ;
      case LOCK4APPEND:
         rc = dfile4lockAppend( lock->data, lock->id.clientId, lock->id.serverId ) ;
         break ;
      case LOCK4FILE:
         rc = dfile4lockFile( lock->data, lock->id.clientId, lock->id.serverId ) ;
         break ;
      case LOCK4RECORD:
         rc = dfile4lock( lock->data, lock->id.clientId, lock->id.serverId, lock->id.recNum ) ;
         break ;
      default:
         rc = error4( lock->data->c4, e4lock, E83901 ) ;
         break ;
   }

   return rc ;
}

int lock4unlock( LOCK4 *lock )
{
   int rc, oldUnlockAuto ;

#ifdef E4ANALYZE
   if ( ( rc = lock4verify( lock, 1 ) ) < 0 )
      return rc ;
#endif

   oldUnlockAuto = code4unlockAuto( lock->data->c4 ) ;
   code4unlockAutoSet( lock->data->c4, 1 ) ;

   switch ( lock->id.type )
   {
      case LOCK4ALL:
         #ifndef N4OTHER
            #ifndef S4MEMO_OFF
               dfile4memoUnlock( lock->data ) ;
            #endif
         #endif
         #ifndef S4INDEX_OFF
            dfile4unlockIndex( lock->data, lock->id.serverId ) ;
         #endif
         rc = dfile4unlockFile( lock->data, lock->id.clientId, lock->id.serverId ) ;
         break ;
      case LOCK4APPEND:
         rc = dfile4unlockAppend( lock->data, lock->id.clientId, lock->id.serverId ) ;
         break ;
      case LOCK4FILE:
         rc = dfile4unlockFile( lock->data, lock->id.clientId, lock->id.serverId ) ;
         break ;
      case LOCK4RECORD:
         rc = dfile4unlockRecord( lock->data, lock->id.clientId, lock->id.serverId, lock->id.recNum ) ;
         break ;
      default:
         rc = error4( lock->data->c4, e4info, E93801 ) ;
         break ;
   }

   code4unlockAutoSet( lock->data->c4, oldUnlockAuto ) ;

   return rc ;
}
#endif  /* S4CLIENT */
#endif  /* S4SINGLE */

/*
int dfile4lockAppendAdd( DATA4 *d4 )
{
   LOCK4 *lock ;
   CODE4 *c4 ;
   int rc ;

   if ( ( rc = d4verify( d4, 1 ) ) < 0 )
      return rc ;

   c4 = d4->codeBase ;

   if ( c4->lockMemory == 0 )
   {
      c4->lockMemory = mem4create( c4, c4->memStartLock, sizeof(TAG4), c4->memExpandLock, 0 ) ;
      if ( c4->lockMemory == 0 )
         return 0 ;
   }

   lock = (LOCK4 *)mem4alloc( c4->lockMemory ) ;
   if ( lock == 0 )
      return error4( c4, e4memory, 0 ) ;

   lock->data = d4->dataFile ;
   lock->type = S4LOCK_APPEND ;
   lock->serverId = data4serverId( d4 ) ;
   lock->clientId = data4clientId( d4 ) ;
   l4add( &d4->trans->locks, lock ) ;

   return 0 ;
}

int dfile4lockFileAdd( DATA4 *d4 )
{
   LOCK4 *lock ;
   CODE4 *c4 ;
   int rc ;

   if ( ( rc = d4verify( d4, 1 ) ) < 0 )
      return rc ;

   c4 = d4->codeBase ;

   if ( c4->lockMemory == 0 )
   {
      c4->lockMemory = mem4create( c4, c4->memStartLock, sizeof(TAG4), c4->memExpandLock, 0 ) ;
      if ( c4->lockMemory == 0 )
         return 0 ;
   }

   lock = (LOCK4 *)mem4alloc( c4->lockMemory ) ;
   if ( lock == 0 )
      return error4( c4, e4memory, 0 ) ;

   lock->data = d4->dataFile ;
   lock->type = S4LOCK_FILE ;
   lock->serverId = data4serverId( d4 ) ;
   lock->clientId = data4clientId( d4 ) ;
   l4add( &d4->trans->locks, lock ) ;
   return 0 ;
}

int dfile4lockRecordAdd( DATA4 *d4, long rec )
{
   LOCK4 *lock ;
   CODE4 *c4 ;
   int rc ;

   if ( ( rc = d4verify( d4, 1 ) ) < 0 )
      return rc ;

   c4 = d4->codeBase ;

   if ( c4->lockMemory == 0 )
   {
      c4->lockMemory = mem4create( c4, c4->memStartLock, sizeof(TAG4), c4->memExpandLock, 0 ) ;
      if ( c4->lockMemory == 0 )
         return 0 ;
   }

   lock = (LOCK4 *)mem4alloc( c4->lockMemory ) ;
   if ( lock == 0 )
      return error4( c4, e4memory, 0 ) ;

   lock->data = d4->dataFile ;
   lock->type = S4LOCK_RECORD ;
   lock->recNum = rec ;
   lock->serverId = data4serverId( d4 ) ;
   lock->clientId = data4clientId( d4 ) ;

   l4add( &d4->trans->locks, lock ) ;
   return 0 ;
}
*/

#ifndef S4OFF_COMMUNICATIONS
void message4release( CODE4 *c4 )
{
   MESSAGE4 *message ;

   for ( ;; )
   {
      message = (MESSAGE4 *)l4first( &c4->availMessages ) ;
      if ( message == 0 )
         return ;
      l4remove( &c4->availMessages, message ) ;
      if ( message->packet != 0 )
      {
         u4free( message->packet ) ;
         message->packet = 0 ;
      }
      u4free( message ) ;
   }
}

void S4FUNCTION message4free( CODE4 *c4, MESSAGE4 *message )
{
   if ( message->packet != 0 )
   {
      if ( c4 == 0 )
      {
         if ( message->packet != 0 )
         {
            u4free( message->packet ) ;
            message->packet = 0 ;
         }
         u4free( message ) ;
      }
      else
         l4add( &c4->availMessages, message ) ;
   }
}

MESSAGE4 * S4FUNCTION message4alloc( CODE4 *c4, unsigned int sizePacket )
{
   MESSAGE4 *message ;

   #ifdef E4PARM_LOW
      if ( c4 == 0 )
      {
         error4( 0, e4parm_null, E93904 ) ;
         return 0 ;
      }

      if ( sizePacket < sizeof( PACKET4 ) )
      {
         error4( 0, e4parm, E93904 ) ;
         return 0 ;
      }
   #endif

   message = 0 ;
   for( ;; )
   {
      message = (MESSAGE4 *)l4next( &c4->availMessages, message ) ;
      if ( message == 0 )
      {
         message = (MESSAGE4 *)u4allocFree( c4, (long)sizeof( MESSAGE4 ) ) ;
         if ( message == 0 )
         {
            #ifdef E4STACK
               error4stack( c4, e4memory, E93904 ) ;
            #endif
            return 0 ;
         }

         message->packet = (PACKET4 *)u4allocFree( c4, (long)sizePacket ) ;
         if ( message->packet == 0 )
         {
            #ifdef E4STACK
               error4stack( c4, e4memory, E93904 ) ;
            #endif
            return 0 ;
         }
         message->len = sizePacket ;
         break ;
      }
      else
         if ( message->len >= sizePacket )
         {
            l4remove( &c4->availMessages, message ) ;
            break ;
         }
   }
   return message ;
}
#endif