/*
 * ISTART.C - setup for sequential I/O
 *
 *                      Copyright (c) 1987, Jim Mischel
 * Modifications:
 *
 * 08/13/87 - jim - original coding
 */

#include "inxdefs.h"

/*
 * istart() - Initialize file for sequential read.  Returns 0 if successful,
 * EOF if unsuccessful.  No data is transferred.
 */
int istart(void *d, char cond, void *src)
{
  register df_rec *db_control = (df_rec *)d;
  char *source = (char *)src;

  db_control->df_flags |= (DF_EOF + DF_TOF);    /* if start fails, EOF is signaled */

  if (cond == START_FILE) {
    /*
     * Start at the beginning of the file.  Get the root, then traverse left
     * nodes until left node is a thread pointer.  If the root is non-existent,
     * return EOF.
     */
    if (iget_root(db_control))
      return(EOF);                      /* couldn't get the root */

    /* found the root, now travel down the left nodes */
    while (!(db_control->df_inx_buff.if_flags & LTHRD))
      if (iread_inx(db_control,db_control->df_inx_buff.if_left_node))
        return(EOF);
  }
  else if (cond == END_FILE) {
    /*
     * Start at the end of the file.  Get the root, then traverse right
     * nodes until right node is a thread pointer.  If the root is
     * non-existent, return EOF.
     */
    if (iget_root(db_control))
      return(EOF);                      /* must be empty file */

    /* found the root, now travel down the right nodes */
    while (!(db_control->df_inx_buff.if_flags & RTHRD))
      if (iread_inx(db_control,db_control->df_inx_buff.if_right_node))
        return(EOF);
  }
  else {
    /* search for the key */
    switch (isearch(db_control,(source+db_control->df_key_offset))) {
      case -1   :                       /* supplied key < last record read */
        if (cond == GE || cond == GT) {
          if (iget_next(db_control,&db_control->df_inx_buff))
            return(EOF);
        }
        else if (cond == EQ)
          return(EOF);
        break;
      case 0    :                       /* supplied key == last record read */
        if (cond == GT) {
          if (iget_next(db_control,&db_control->df_inx_buff))
            return(EOF);
        }
        else if (cond == LT)
          if (iget_prev(db_control,&db_control->df_inx_buff))
            return(EOF);
        break;
      case 1    :                       /* supplied key > last record read */
        if (cond == LE || cond == LT) {
          if (iget_prev(db_control,&db_control->df_inx_buff))
            return(EOF);
        }
        else if (cond == EQ)
          return(EOF);
        break;
      default   : return(EOF);          /* some error occured during search */
    } /* switch */
  } /* else */

  db_control->df_flags &= ~(DF_EOF | DF_TOF);
  db_control->df_flags |= DF_START;

  /* copy index buffer into next buffer for readnext operations */
  memcpy(&db_control->df_nxt_buff,&db_control->df_inx_buff,sizeof(inx_rec));
  return(0);
} /* istart */
