n_regtexiscb() - Register hit callback function

SYNOPSIS

#include <sys/types.h>
#include "tstone.h"
FLDLST
{
 int    n;            /* number of items in each of following lists */
 int   *type;                           /* types of field (FTN_xxx) */
 void **data;                                 /* data array pointer */
 int   *ndata;                  /* number of elements in data array */
 char **name;                                      /* name of field */
};
int n_regtexiscb(SERVER *se,void *usr,
                 int (*cb)(void *usr,TEXIS *tx,FLDLST *fl) );


DESCRIPTION
This function assigns the callback routine that the server is to call each time it locates an item that matches the user's query. The client program can pass along a pointer to a "user" object to the register function that will be in turn passed to the callback routine on each invocation.

The callback routine also gets a TEXIS handle that can be used to get further information about the hit (see n_getsrchlst()) and a FLDLST handle that contains the selected fields.

A FLDLST is a structure containing parallel arrays of information about the selected fields and a count of those fields. FLDLST members:

int n -- The number of fields in the following lists.

int *type -- An array of types of the fields. Each element will be one of the FTN_xxxx macros.

void **data -- An array of data pointers. Each element will point to the data for the field. The data for a field is an array of types.

int *ndata -- An array of data counts. Each element says how many elements are in the data array for this field.

char **name -- An array of strings containing the names of the fields.

SRCHLST *sl -- An array of SRCHLSTs containing information Metamorph searches, if any. Filled in, on request only, by n_fillsrchlst().

MMOFFS mmoff -- An array of Metamorph subhit offsets and lengths from Metamorph searches, if any. Filled in, on request only, by n_fillsrchlst().

Possible types in FLDLST->type array:

FTN_BYTE -- An 8 bit byte.

FTN_CHAR -- A char.

FTN_DOUBLE -- A double.

FTN_DATE -- A long in the same form as that from the time() system call.

FTN_DWORD -- A 32 bit dword.

FTN_FLOAT -- A float.

FTN_INT -- An int.

FTN_INTEGER -- An int.

FTN_LONG -- A long.

FTN_INT64 -- An int64.

FTN_UINT64 -- A uint64.

FTN_SHORT -- A short.

FTN_SMALLINT -- A short.

FTN_WORD -- A 16 bit word.

FTN_INDIRECT -- A char string URL indicating the file that the data for this field is stored in.

FTN_COUNTER -- A ft_counter structure containing a unique serial number.

FTN_STRLST -- A delimited list of strings.

The type may also be |ed with FTN_NotNullableFlag (formerly DDNULLBIT) and/or DDVARBIT. If FTN_NotNullableFlag is set, it indicates that the field is not allowed to be NULL. DDVARBIT indicated that the field is variable length instead of fixed length. When handling result rows these bits can generally be ignored.

n_regtexiscb() will return true if the registration was successful, and will return false (0) on error.


EXAMPLE

#include <sys/types.h>
#include "tstone.h"

#define USERDATA my_data_structure
USERDATA
{
 FILE   *outfile;  /* where I will log the hits */
 long   hitcount;  /* just for fun */
};

void
dispnames(ud,fl)                         /* display all field names */
USERDATA *ud;
FLDLST *fl;
{
 int i;

 for(i=0;i<fl->n;i++)                                /* every field */
    printf("%s ",fl->name[i]);
 putchar('\n');                                  /* end header line */
}

void
dispfields(ud,fl)                 /* display all fields of any type */
USERDATA *ud;
FLDLST *fl;
{
 int i, j;

 for(i=0;i<fl->n;i++)
    {
     int   type=fl->type[i];                   /* the type of field */
     void *p   =fl->data[i];                 /* pointer to the data */
     int   n   =fl->ndata;                     /* how many elements */
     if(i>0) putchar('\t');  /* tab between fields, but not leading */
     switch (type & DDTYPEBITS) /* ignore NULL and VAR bits */
        {
                        /* loop through each element of field via j */
                                /* cast and print according to type */
         case FTN_BYTE    : for(j=0;j<n;j++)
                             printf("0x%x ",((byte *)p)[j]);
                            break;
         case FTN_INDIRECT: /*nobreak;*/
                            /* just print the filename as a string */
         case FTN_CHAR    : for(j=0;j<n && ((char *)p)[j]!='\0';j++)
                             printf("%c"  ,((char *)p)[j]);
                            break;
         case FTN_DOUBLE  : for(j=0;j<n;j++)
                             printf("%lf ",((double *)p)[j]);
                            break;
         case FTN_DWORD   : for(j=0;j<n;j++)
                             printf("%lu ",
                                    (unsigned long)((dword *)p)[j]);
                            break;
         case FTN_FLOAT   : for(j=0;j<n;j++)
                             printf("%f " ,((float *)p)[j]);
                            break;
         case FTN_INT     : for(j=0;j<n;j++)
                             printf("%d " ,((int *)p)[j]);
                            break;
         case FTN_INTEGER : for(j=0;j<n;j++)
                             printf("%d " ,((int *)p)[j]);
                            break;
         case FTN_LONG    : for(j=0;j<n;j++)
                             printf("%ld ",((long *)p)[j]);
                            break;
         case FTN_SHORT   : for(j=0;j<n;j++)
                             printf("%d " ,((short *)p)[j]);
                            break;
         case FTN_SMALLINT: for(j=0;j<n;j++)
                             printf("%d " ,((short *)p)[j]);
                            break;
         case FTN_WORD    : for(j=0;j<n;j++)
                             printf("%u " ,
                                    (unsigned int)((word *)p)[j]);
                            break;
          /* assume exactly one element on FTN_DATE for this example */
         case FTN_DATE    : printf("%.25s",ctime(p));/* human format */
                            break;
         case FTN_COUNTER : printf("%08lx%08lx",((ft_counter *)p)->date,
                                                ((ft_counter *)p)->seq);
                            break;
         case FTN_STRLST  : {
                             size_t nb=((ft_strlst *)p)->nb;
                             char delim=((ft_strlst *)p)->delim;
                             char *b=((ft_strlst *)p)->buf;
                                for(j=0;j<nb;j++)
                                {
                                   if(b[j]=='\0') putchar(delim);
                                   else           putchar(b[j]);
                                }
                            }
                            break;
         default          : printf("unknowntype(%d)",type);
        }
    }
}

int
hit_handler(usr,tx,fl)
void *usr;  /* my user-data pointer */
TEXIS *tx;  /* Texis API handle */
FLDLST *fl; /* The field list data structure */
{
 USERDATA *ud=(USERDATA *)usr;  /* cast the void into the real type */

 ++ud->hitcount;                      /* add one to the hit counter */

 if(ud->hitcount==1)                        /* before the first hit */
    dispnames(ud,fl);             /* display all of the field names */
 dispfields(ud,fl);                    /* display all of the fields */

 if(ud->hitcount>=100)/* tell the server to stop if I've seen enough */
    return(0);
 return(1);          /* tell the server to keep giving me more hits */
}

int
main()
{
 SERVER  *se;
 USERDATA mydata;
 ...
 mydata.outfile=(FILE *)NULL;
 mydata.hitcount=0;
 n_regtexiscb(se,&mydata,hit_handler);
 ...
}


SEE ALSO
The example program netex3.c.


Copyright © Thunderstone Software     Last updated: Dec 10 2018
Copyright © 2019 Thunderstone Software LLC. All rights reserved.