
/* This program checks our ability to use only the object file and the */
/*  header file supplied to compile a program.  Use the following      */
/*  command line to compile this program for Borland C++:              */
/*      bcc -ml i_f_eng.obj i_f_test.c                                 */
/*  The format should be similar for other compilers; I don't know.    */
/*  Remember that the i_f_eng.obj file is compiled with the large      */
/*  memory model.                                                      */
/*                                                                     */
/* The program is also an example of how to use structures with the    */
/*  engine (such as when each record is contained in a structure).     */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#include "i_f_eng.h"

void main()
{
int phonelist_file;  /* A file handle always needs to be defined.  */
char phonelist_file_id[] = "phonelst.ife";
struct  {
    char phone_number[10];  /* This is the 1st key. */
    char name[40];          /* This is the 2nd key. */
    short number_of_calls;  /* This is the rest of the data in the record. */
    char junk[30];
    }  phonelist_record;
int errcode;  /* Used for saving the return code from indexed_file(). */
char temp_string[11];  /* This is used in several places in this program. */

/* By looking at the structure above, we can see we have a record length */
/*  of 82 with 2 keys.  First key is at offset 0, 10 chars. long, with   */
/*  no duplicates.  2nd key (the name) is at offset 10, 40 chars. long,  */
/*  with duplicates allowed.                                             */
strcpy(I_F_FILE_ATTRIBUTES,"82 2 0 10 0 10 40 1");

printf("  File attributes: %s\n",I_F_FILE_ATTRIBUTES);

printf("Creating file with these attributes.\n");
errcode = indexed_file(&phonelist_file,I_F_OPEN_WRITE,phonelist_file_id,0);
if (errcode)  {
    printf("?Error creating indexed file; error code: %d\n",errcode);
    printf(" See I_F_ENG.H for a listing of error codes and their meanings.\n");
    exit(1);  }


/* Now we have successfully figured the attributes and opened the file. */
/*  It's time to show how to write a record out.                        */

/* How to use memcpy (we don't want the trailing null which strcpy() would write after the data). */
memcpy(phonelist_record.phone_number,"5123839853",10);

phonelist_record.number_of_calls = 0;

/* How to use strcpy to put string data in a field.  The data must be at */
/*  least one byte shorter than the field (so there's space for trailing */
/*  null) or the data and null will overwrite the next field (or cause   */
/*  other problems).                                                     */
phonelist_record.name[0] = 0;  /* Initialize the string. */
strncat(phonelist_record.name,"Moore,Alton",39); /* Leave one space for null. */

/* Set the junk field to all nulls. */
memset(phonelist_record.junk,0,sizeof(phonelist_record.junk));

printf("Writing out test record.\n");
errcode = indexed_file(&phonelist_file,I_F_WRITE,&phonelist_record,0);
if (errcode)  {
    printf("?Problem writing record to file; error code: %d\n",errcode);
    printf(" See I_F_ENG.H for a listing of error codes and their meanings.\n");
    exit(1);  }

printf("Closing file.\n");
errcode = indexed_file(&phonelist_file,I_F_CLOSE,"",0);
if (errcode)  {
    printf("?Problem closing file!  Unusual!  Error code: %d\n",errcode);
    printf(" See I_F_ENG.H for a listing of error codes and their meanings.\n");
    exit(1);  }

printf("Opening file for read.\n");
errcode = indexed_file(&phonelist_file,I_F_OPEN_READ,phonelist_file_id,0);
if (errcode)  {
    printf("?Error opening the file we just wrote out; errorcode: %d\n",errcode);
    printf(" See I_F_ENG.H for a listing of error codes and their meanings.\n");
    exit(1);  }

printf("The records in the file are:\n");
memset(phonelist_record.name,0,40);  /* Set the name key to all nulls. */
if (indexed_file(&phonelist_file,I_F_START,&phonelist_record,1))  {  /* Start by the 2nd key. */
    printf("?Error starting file we just wrote out!  File shouldn't be empty!\n");
    exit(1);  }    /* Here we just do the start in the if statement.  This is just another way of calling the routine. */

while (!indexed_file(&phonelist_file,I_F_READNEXT,&phonelist_record,0))  {
    memcpy(temp_string,phonelist_record.phone_number,10);  /* We need to stick a null at the end of this to print it as a string. */
    temp_string[10] = 0;
    printf("  Name: %s      Phone number: %s \n",phonelist_record.name,temp_string);  }

indexed_file(&phonelist_file,I_F_CLOSE,"",0);  /* Don't bother checking for close error; they never happen anyway! */

printf("Done!\n");
}



/* I used the extension .ife (Indexed File Engine) for the indexed file  */
/*  because I think it's a good convention.  If your installation has    */
/*  another standard suffix or naming scheme for this type of file, then */
/*  use that.  If not, I guess the extension .IFE is as good as any.  In */
/*  any case, the indexed file engine cares not what you use.            */

