home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
samtexco.zip
/
imlsmp01.c
< prev
next >
Wrap
Text File
|
2000-03-31
|
135KB
|
2,186 lines
/*====================================================================*/
/* */
/* IBM Text Search API Sample Application Program */
/* */
/*====================================================================*/
/* */
/* Name: IMLSMP01.C */
/* ----- */
/* */
/* COPYRIGHT: */
/* ---------- */
/* Digital Library Version 2 - 5648-A08. */
/* (C) Copyright IBM Corp. 1996. */
/* All Rights Reserved */
/* US Government Users Restricted Rights */
/* Use, duplication or disclosure restricted */
/* by GSA ADP Schedule */
/* Contract with IBM Corp. */
/* Licensed Materials - Property of IBM */
/* */
/* DISCLAIMER OF WARRANTIES: */
/* ------------------------- */
/* The following [enclosed] code is sample code created by IBM */
/* Corporation. This sample code is not part of any standard IBM */
/* product and is provided to you solely for the purpose of */
/* assisting you in the development of your applications. */
/* The code is provided "AS IS", without warranty of any kind. */
/* IBM shall not be liable for any damages arising out of your */
/* use of the sample code, even if they have been advised of the */
/* possibility of such damages. */
/* */
/*====================================================================*/
/*====================================================================*/
/* IMLSMP01.c (API Sample Application Program) */
/*====================================================================*/
/*=====================================================================+
| |
| Title: IBM Text Search Sample Application Program |
| |
| Purpose: Template for a C application program that uses the |
| IBM Text Search Application Program Interface. |
| |
| The IBM Text Search Sample Application Program |
| has to be considered as an appendix document to the |
| IBM Text Search Application Program Interface |
| Guide and Reference (SH12-6317-00) |
| rather than as a complete application to be run on |
| your work station. |
| |
| The program shows |
| - the natural sequence of API function calls |
| - how to intercept the API function return codes |
| - how to build datastream input for API functions |
| - how to parse datastream output from API functions |
| - how to use the macros VAL2() and ID() |
| |
| Operation: - Builds a server table containing all Text Search |
| servers that can be connected to the application. |
| - Starts a session with one of the servers from the |
| server table. |
| - Collects all information retrieval indexes that |
| can be accessed from the current session in an |
| index table. |
| - Opens an index contained in the index table and |
| adds the index information to the index table. |
| - Builds a query datastream and issues a search |
| request. |
| - If there are documents found: |
| - Obtains the result information and attaches it to |
| the current index information. |
| - Deletes the current search result. |
| - Closes the current information-retrieval index. |
| - Ends the current information-retrieval session. |
| |
| API function calls: |
| |
| EhwListServers |
| EhwStartSession |
| EhwListIndexes |
| EhwOpenIndex |
| EhwGetIndexInfo |
| EhwSearch |
| EhwListResult |
| EhwDeleteResult |
| EhwCloseIndex |
| EhwEndSession |
| |
| Notes: With the current design the program is prepared to |
| handle parallel sessions with multiple open indexes. |
| |
| For the sake of simplicity there is only one search |
| result per index maintained at a time. |
| |
| Dependencies: |
| |
| |
+=====================================================================*/
/*=====================================================================+
| |
| Entry point: main |
| |
| Function: Demonstrates how a C application program can use the |
| IBM Text Search Application Program Interface. |
| |
| Input |
| parameters: None |
| |
| Output |
| parameters: None |
| |
| Return codes: Status ok RC_TRUE |
| Status not ok RC_FALSE |
| |
| Input files: None |
| |
| Output files: None |
| |
| Calls: Internal functions: |
| |
| WriteDataStream |
| ListServers |
| ListIndexes |
| OpenIndex |
| ListResult |
| DeleteResult |
| HandleError |
| |
| API functions: |
| |
| EhwStartSession |
| EhwSearch |
| EhwCloseIndex |
| EhwEndSession |
| |
| Exits: Returns to caller |
| |
|----------------------------------------------------------------------|
| |
| Program logic: |
| |
| - Allocate a work area used to hold API datastreams. |
| |
| - Call the internal function ListServers to build a server table |
| containing all Text Search servers that can be connected to |
| the application. |
| - Check the function status code. |
| |
| - Select one server name from the server table. |
| - Write the session information datastream to a work area using |
| the internal function WriteDataItem. |
| - Invoke the API service EhwStartSession to connect |
| to the selected server and to start a session. |
| - Check the API function return code. |
| |
| - Call the internal function ListIndexes to build an index table |
| and to create an index information for any index entry. |
| - As there is presently only one index defined for any server, |
| the index table will contain only one index entry. |
| With the current design, the ListIndexes function is prepared |
| for future IBM Text Search extensions. |
| - Check the function status code. |
| |
| - Selects one index name from the index table. |
| - Invoke the internal function OpenIndex to open the selected index |
| and to complete the index information for this index. |
| - Check the function status code. |
| |
| - Build a query datastream using function WriteDataItem. |
| - Issue an EhwSearch function call to process the query. |
| - Check the API function return code. |
| |
| - If the result size is greater than zero |
| - Call the internal function ListResult to build the |
| result information and to anchor it in the current |
| index information. |
| - Check the function status code. |
| - Invoke the internal function DeleteResult to release |
| the recent result information. |
| - Check the function status code. |
| Endif |
| |
| - Issue an EhwCloseIndex function call to close the current |
| information-retrieval index. |
| - Check the API function return code. |
| - Reset the index handle field of the current index information. |
| |
| - Issue an EhwEndSession function call to end the current session. |
| - Check the API function return code. |
| - Release the index table and all anchored index information areas. |
| |
| - Release the server table. |
| - Release the work area. |
| |
| - Return to the caller. |
| |
+=====================================================================*/
/*--------------------------------------------------------------------*/
/* external definitions */
/*--------------------------------------------------------------------*/
#if defined (__WINDOWS__)
#include <windows.h>
#define __WINDOWS_H 1
#endif
#include <stdio.h> /* => printf () */
#include <stdlib.h> /* standard library functions */
#include <string.h> /* string handling functions */
#include <imoapic.h> /* API definitions for C */
#if defined (__UNIX__)
#include "ehwlsgvi.h"
#include <time.h>
#endif
/*--------------------------------------------------------------------*/
/* internal definitions */
/*--------------------------------------------------------------------*/
#include "imlsmp01.h" /* API sample definitions */
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __cplusplus
}
#endif
/*====================================================================*/
/* main function (IMLSMP01.c) */
/*====================================================================*/
INT main /* Sample Application Program */
(
INT argc, PCHAR argv[], PCHAR envp[]
) /* function value: status code */
{ /* function variables: */
ULONG ulReturnCode = RC_DONE;/* API return code */
ULONG ulDiagnosisInfo = 0L; /* API diagnosis information */
ULONG ulIndexHandle = 0L; /* API index handle */
ULONG ulResultHandle = 0L; /* API result handle */
ULONG ulResultSize = 0L; /* API result size */
ULONG ulDataLength = 0L; /* API datastream length */
PCHAR pDataStream = NULL; /* API datastream pointer */
PVOID pSession = NULL; /* API session pointer */
USHORT usValue = 0; /* USHORT datastream value */
INT iCount = 0; /* loop variable */
INT iStatus = RC_TRUE;/* WriteDataItem() status code */
PCHAR pArea = NULL; /* pointer to work area */
PSRVTBL pServerTable = NULL; /* pointer to server table */
PSERVER pServer = NULL; /* server table entry pointer */
PXTBL pIndexTable = NULL; /* pointer to index table */
PINDEX pIndex = NULL; /* index information pointer */
PPINDEX ppIndex = NULL; /* ptr to index info. pointer */
CHAR Work[250]; // work area
UCHAR word1[50];
UCHAR word2[50];
/*-----------------------------------------------------------------*/
/* initialization / processing */
/*-----------------------------------------------------------------*/
memset(Work, 0x00, sizeof(Work));
memset(word1, 0x00, sizeof(word1));
memset(word2, 0x00, sizeof(word2));
//---------------------------------------------------------
// only words entered in the cmd line are searched for
//---------------------------------------------------------
if(argc >1)
strcpy(word1, argv[1]);
else
strcpy(word1, QUERY_WORD01);
if(argc >2)
strcpy(word2, argv[2]);
else
strcpy(word2, QUERY_WORD02);
printf( " search term1 = %s \n", word1);
printf( " search term2 = %s \n", word2);
/*-----------------------------------------------------------------*/
/* allocate a work area to hold datastream information */
/*-----------------------------------------------------------------*/
pArea = malloc(SIZEOF_DATA_AREA); /* allocate the work area */
if (!pArea) /* check if allocation failed */
{
/*--------------------------------------------------------------*/
/* handle the allocation error ... */
/*--------------------------------------------------------------*/
return (RC_FALSE); /* return to the caller */
} /* endif allocation failed */
/*-----------------------------------------------------------------*/
/* get a list of all AIR servers that are known on your client */
/* call function ListServers to build a server table */
/*-----------------------------------------------------------------*/
iStatus = ListServers (&pServerTable);
if (iStatus != RC_TRUE) /* check ListServers status */
{
/*--------------------------------------------------------------*/
/* handle the function error ... */
/*--------------------------------------------------------------*/
free(pArea); /* release the work area */
return (iStatus); /* return to the caller */
} /* endif ListServers failed */
/*-----------------------------------------------------------------*/
/* select an information-retrieval server: */
/* - either the first server of the server table that comlies with */
/* the server location specification (SESSION_IRSL) */
/* - or the last server of the server table */
/*-----------------------------------------------------------------*/
pServer = pServerTable->Server; /* set server table entry ptr */
for (iCount = pServerTable->usServerCount - 1; iCount > 0; iCount--)
{
if (pServer->Location == SESSION_IRSL) break;
pServer = (PSERVER )((PCHAR )pServer + (offsetof(SERVER, Name[0])
+ pServer->usNameLength));
}
/*-----------------------------------------------------------------*/
/* write the session information datastream to the work area */
/*-----------------------------------------------------------------*/
ulDataLength = SIZEOF_DATA_AREA; /* initialize remaining length */
pDataStream = pArea; /* initialize target pointer */
/* write XNAM item */
iStatus = WriteDataItem (ID_IRSN, IT_ATOMIC,
pServer->usNameLength,
(PCHAR )pServer->Name,
&ulDataLength, &pDataStream);
if (iStatus != RC_TRUE) /* check WriteDataItem status */
{ /* area is too small to hold */
/* the session information */
/*--------------------------------------------------------------*/
/* handle the function error ... */
/*--------------------------------------------------------------*/
free(pServerTable); /* release the server table */
free(pArea); /* release the work area */
return (iStatus); /* return to the caller */
}
/* set length of session info. */
ulDataLength = (ULONG )(pDataStream - pArea);
pDataStream = pArea; /* set pointer to datastream */
/*-----------------------------------------------------------------*/
/* start a session, using API service EhwStartSession */
/*-----------------------------------------------------------------*/
ulReturnCode =
EhwStartSession (ulDataLength, /* In -- datastream length */
pDataStream, /* In -- session information */
&pSession, /* Out -- session pointer */
&ulDiagnosisInfo); /* Out -- diagnosis info. */
printf ("ReturnCode (EhwStartSession) = %d \n", ulReturnCode);
if (ulReturnCode != RC_DONE) /* check the API return code */
{
/*--------------------------------------------------------------*/
/* handle the function error ... */
/*--------------------------------------------------------------*/
free(pServerTable); /* release the server table */
free(pArea); /* release the work area */
printf("Start Session failed for Text Search server %s \n", pServer->Name);
return (RC_FALSE); /* return to the caller */
} /* endif API call failed */
printf("Start Session successful for Text Search server %s \n", pServer->Name);
/*-----------------------------------------------------------------*/
/* save the session pointer in the current server information */
/*-----------------------------------------------------------------*/
pServer->pSession = pSession;
/*-----------------------------------------------------------------*/
/* create an index table that holds the accessible information */
/* retrieval indexes (at most LT_NUMBER_OF_INDEXES entries) by */
/* invoking the internal function ListIndexes */
/*-----------------------------------------------------------------*/
iStatus = ListIndexes (pSession, /* In -- session pointer */
&pIndexTable /* In/Out index table pointer */
);
if (iStatus != RC_TRUE) /* check ListServers status */
{ /* server table is not built */
/*--------------------------------------------------------------*/
/* handle the function error ... */
/*--------------------------------------------------------------*/
HandleError (pServerTable, /* In -- server table pointer */
pArea); /* In -- work area pointer */
return (iStatus); /* return to the caller */
} /* endif ListIndexes failed */
/*-----------------------------------------------------------------*/
/* save the index table in the current server information */
/*-----------------------------------------------------------------*/
pServer->pIndexTable = pIndexTable;
/*-----------------------------------------------------------------*/
/* select the first index information entry in the index table */
/*-----------------------------------------------------------------*/
ppIndex = pIndexTable->pIndex; /* access the index info. ptr */
/*-----------------------------------------------------------------*/
/* open the specified index, complete its information structure */
/* invoke internal function OpenIndex */
/*-----------------------------------------------------------------*/
iStatus = OpenIndex (pSession, /* In -- session pointer */
ppIndex); /* In/Out index info. (ptr) */
if (iStatus != RC_TRUE) /* check OpenIndex status */
{ /* index info. is not modified */
/*--------------------------------------------------------------*/
/* handle the function error ... */
/*--------------------------------------------------------------*/
HandleError (pServerTable, /* In -- server table pointer */
pArea); /* In -- work area pointer */
// memcpy(Work, ppIndex->pName->Data, VAL2(&(pIndex->pName->ll))-5 );
printf( " OpenIndex failed index: \n");
return (iStatus); /* return to the caller */
} /* endif OpenIndex failed */
/*-----------------------------------------------------------------*/
/* set current index information pointer */
/*-----------------------------------------------------------------*/
pIndex = *ppIndex;
/*------------------------------------------------------------------+
| <start of the search processing> |
+------------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/* write a query datastream to the work area */
/*-----------------------------------------------------------------*/
ulDataLength = SIZEOF_DATA_AREA; /* initialize remaining length */
pDataStream = pArea; /* initialize target pointer */
/* write CCSID item */
/* invert the CCSID item value */
/* to big-endian format */
usValue = ID(QUERY_CCSID); /* using macro ID() or VAL2() */
iStatus = WriteDataItem (ID_CCSID, IT_ATOMIC,
(USHORT )sizeof(usValue), (PCHAR )&usValue,
&ulDataLength, &pDataStream);
/* write language id item */
/* invert the language id item */
/* value to big-endian format */
usValue = ID(QUERY_LANG); /* using macro ID() or VAL2() */
iStatus = iStatus &
WriteDataItem (ID_LANG, IT_ATOMIC,
(USHORT )sizeof(usValue), (PCHAR )&usValue,
&ulDataLength, &pDataStream);
/* write SARG start item */
iStatus = iStatus &
WriteDataItem (ID_SARG, IT_START, 0, NULL,
&ulDataLength, &pDataStream);
/* write TERM item */
iStatus = iStatus &
WriteDataItem (ID_TERM, IT_ATOMIC,
strlen(word1), word1,
&ulDataLength, &pDataStream);
/* write SARG end item */
iStatus = iStatus &
WriteDataItem (ID_SARG, IT_END, 0, NULL,
&ulDataLength, &pDataStream);
/* write AND item */
if( strlen(word2) > 0)
{
iStatus = iStatus &
WriteDataItem (ID_LOR, IT_ATOMIC, 0, NULL,
// WriteDataItem (ID_AND, IT_ATOMIC, 0, NULL, // to AND the terms
&ulDataLength, &pDataStream);
/* write SARG start item */
iStatus = iStatus &
WriteDataItem (ID_SARG, IT_START, 0, NULL,
&ulDataLength, &pDataStream);
/* write TERM item */
iStatus = iStatus &
WriteDataItem (ID_TERM, IT_ATOMIC,
strlen(word2), word2,
&ulDataLength, &pDataStream);
// (USHORT )(sizeof(QUERY_WORD02) - 1),
// QUERY_WORD02,
/* write SARG end item */
iStatus = iStatus &
WriteDataItem (ID_SARG, IT_END, 0, NULL,
&ulDataLength, &pDataStream);
}
if (iStatus != RC_TRUE) /* check WriteDataItem status */
{ /* area is too small to hold */
/* the session information */
/*--------------------------------------------------------------*/
/* handle the function error ... */
/*--------------------------------------------------------------*/
HandleError (pServerTable, /* In -- server table pointer */
pArea); /* In -- work area pointer */
return (iStatus); /* return to the caller */
}
/* set length of query data */
ulDataLength = (ULONG )(pDataStream - pArea);
pDataStream = pArea; /* set pointer to datastream */
/*-----------------------------------------------------------------*/
/* start a search using API service EhwSearch */
/*-----------------------------------------------------------------*/
ulIndexHandle = pIndex->ulHandle; /* access the index handle */
ulReturnCode =
EhwSearch (pSession, /* In -- session pointer */
ulIndexHandle, /* In -- index handle */
ulDataLength, /* In -- datastream length */
pDataStream, /* In -- query */
&ulResultHandle, /* Out -- result handle */
&ulResultSize, /* Out -- result size */
&ulDiagnosisInfo); /* Out -- diagnosis info */
printf ("ReturnCode (EhwSearch) = %d \n", ulReturnCode);
printf ("ResultSize (EhwSearch) = %d \n", ulResultSize);
if (ulReturnCode != RC_DONE) /* check the API return code */
{
switch (ulReturnCode) /* pick out the warning codes */
{
case RC_DICTIONARY_NOT_FOUND:
case RC_STOPWORD_IGNORED:
/*--------------------------------------------------------*/
/* handle the warning code ... */
/*--------------------------------------------------------*/
break; /* ignore the warning code */
default:
/*--------------------------------------------------------*/
/* handle the function error ... */
/*--------------------------------------------------------*/
HandleError (pServerTable, /* In -- server table pointer */
pArea); /* In -- work area pointer */
return (RC_FALSE); /* return to the caller */
}
} /* endif API call failed */
if (ulResultSize) /* check the result size */
{
/*--------------------------------------------------------------*/
/* build the result information for the current result, */
/* invoke internal function ListResult */
/*--------------------------------------------------------------*/
iStatus =
ListResult (pSession, /* In -- session pointer */
ulResultHandle, /* In -- result handle */
ulResultSize, /* In -- result size */
LT_RESULT_DOCUMENTS, /* In -- reference limit */
pIndex); /* In/Out index information */
if (iStatus != RC_TRUE) /* check OpenIndex status */
{ /* index info. is not modified */
/*-----------------------------------------------------------*/
/* handle the function error ... */
/*-----------------------------------------------------------*/
HandleError (pServerTable, /* In -- server table pointer */
pArea); /* In -- work area pointer */
return (iStatus); /* return to the caller */
} /* endif ListResult failed */
/*--------------------------------------------------------------*/
/* delete the current search result */
/*--------------------------------------------------------------*/
iStatus =
iStatus & DeleteResult (pSession,/* In -- session pointer */
pIndex); /* In/Out index information */
if (iStatus != RC_TRUE) /* check the function status */
{
/*-----------------------------------------------------------*/
/* handle the function error ... */
/*-----------------------------------------------------------*/
HandleError (pServerTable, /* In -- server table pointer */
pArea); /* In -- work area pointer */
return (iStatus); /* return to the caller */
}
} /* endif result size not zero */
/*------------------------------------------------------------------+
| <end of the search processing> |
+------------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/* close the current information retrieval index */
/*-----------------------------------------------------------------*/
ulIndexHandle = pIndex->ulHandle; /* access the index handle */
ulReturnCode =
EhwCloseIndex (pSession, /* In -- session pointer */
ulIndexHandle, /* In -- index handle */
&ulDiagnosisInfo); /* Out -- diagnosis info. */
printf ("ReturnCode (EhwCloseIndex) = %d \n", ulReturnCode);
if (ulReturnCode != RC_DONE) /* check the API return code */
{
/*--------------------------------------------------------------*/
/* handle the function error ... */
/*--------------------------------------------------------------*/
iStatus = RC_FALSE; /* set function status code */
} /* endif API call failed */
/*-----------------------------------------------------------------*/
/* reset the index handle in the current index information */
/*-----------------------------------------------------------------*/
pIndex->ulHandle = 0L;
/*-----------------------------------------------------------------*/
/* end the API session */
/*-----------------------------------------------------------------*/
ulReturnCode =
EhwEndSession (pSession, /* In -- session pointer */
&ulDiagnosisInfo); /* Out -- diagnosis info */
printf ("ReturnCode (EhwEndSession) = %d \n", ulReturnCode);
if (ulReturnCode != RC_DONE) /* check the API return code */
{
/*--------------------------------------------------------------*/
/* handle the function error ... */
/*--------------------------------------------------------------*/
iStatus = RC_FALSE; /* set function status code */
} /* endif API call failed */
/*-----------------------------------------------------------------*/
/* release storage allocated for the current session */
/*-----------------------------------------------------------------*/
pIndex = pIndexTable->pIndex[0]; /* free index related storage */
free(pIndex); /* release current index info. */
// while (pIndexTable->usIndexCount)
// {
// free(pIndex); /* release current index info. */
// pIndex++;
// (pIndexTable->usIndexCount)--;
// }
free(pIndexTable); /* release the index table */
/*-----------------------------------------------------------------*/
/* reset the session pointer in the current server information */
/*-----------------------------------------------------------------*/
pServer->pSession = NULL;
/*-----------------------------------------------------------------*/
/* release remaining storage allocated by the sample application */
/*-----------------------------------------------------------------*/
/* free server related storage */
free(pServerTable); /* release the server table */
free(pArea); /* release the work area */
printf ("StatusCode (IMLSMP01) = %d \n", iStatus);
return (iStatus); /* return to the caller */
} /* end of main function */
/*=====================================================================+
| |
| Entry point: ListServers |
| |
| Function: Builds a server table containing the server |
| information for any IBM Text Search server |
| that can be connected to this application. |
| |
| Input |
| parameters: None |
| |
| Output |
| parameters: Pointer to server table |
| |
| Return codes: Status ok RC_TRUE |
| Status not ok RC_FALSE |
| |
| Input files: None |
| |
| Output files: None |
| |
| Calls: API functions: |
| |
| EhwListServers |
| |
| Exits: Returns to caller |
| |
|----------------------------------------------------------------------|
| |
| Program logic: |
| |
| - Issue an EhwListServers function call to obtain the server list |
| datastream. |
| - Check the API function return code. |
| |
| - Determine the total size of the server table: |
| Length of server list datastream plus size of server table header. |
| - Allocate the server table area in this size. |
| - Initialize the server table header fields: |
| Header text, length of table and number of server entries. |
| |
| - Parse the server list datastream: |
| While current data pointer has not yet reached the end of data |
| |
| - Select the item identifier |
| |
| - When ID_IRS (server list delimiter) |
| |
| - If it is an end item (item type = IT_END) |
| |
| - Increase the server count. |
| - Skip the current server entry. |
| |
| Else (item is of type IT_START) |
| |
| - Initialize the session pointer. |
| - Initialize the index table pointer. |
| |
| Endif |
| |
| - When ID_IRSN (server name item) |
| |
| - Set the server name length and |
| the server name of current server information structure. |
| |
| - When ID_IRSL (server location item) |
| |
| - Set the server location. |
| |
| - Otherwise - |
| |
| Endselect |
| |
| - Update the data pointer (skip current item). |
| |
| Endwhile |
| |
| - Assign the address of the server table to the output parameter. |
| - Return to the caller. |
| |
+=====================================================================*/
/*====================================================================*/
/* internal function ListServers (build the ServerTable) */
/*====================================================================*/
INT ListServers /* hold the servers in a table */
(
SRVTBL **ppServerTable /* Out -- server table pointer */
) /* function value: status code */
{ /* function variables: */
ULONG ulReturnCode = RC_DONE;/* API return code */
ULONG ulDiagnosisInfo = 0L; /* API diagnosis information */
ULONG ulDataLength = 0L; /* API datastream length */
PCHAR pDataStream = NULL; /* API datastream pointer */
PCHAR pDataEnd = NULL; /* end of datastream pointer */
PSERVER pServer = NULL; /* server table entry pointer */
PSRVTBL pServerTable = NULL; /* server table pointer */
ULONG ulTableLength = 0L; /* length of server table */
/*-------------------------------------------------------------------*/
/* initialize the output parameter (pointer to server table) */
/*-------------------------------------------------------------------*/
*ppServerTable = NULL;
/*-------------------------------------------------------------------*/
/* call API service EhwListServers */
/*-------------------------------------------------------------------*/
ulReturnCode =
EhwListServers (&ulDataLength, /* Out -- datastream length */
&pDataStream, /* Out -- server list */
&ulDiagnosisInfo); /* Out -- diagnosis info. */
printf ("ReturnCode (EhwListServers) = %d \n", ulReturnCode);
if (ulReturnCode != RC_DONE) /* check the API return code */
{
/*--------------------------------------------------------------*/
/* handle the API error ... */
/*--------------------------------------------------------------*/
return (RC_FALSE); /* return to the caller */
} /* endif API call failed */
/*-----------------------------------------------------------------*/
/* allocate / initialize the server table to hold the server list */
/*-----------------------------------------------------------------*/
/* The size of the server table may be reduced if you first parse */
/* the datastream to determine the number of servers. Then the */
/* actual size to be allocated can be calculated. */
/*-----------------------------------------------------------------*/
/* set the server table length */
ulTableLength = ulDataLength + offsetof(SRVTBL, Server[0]);
pServerTable = (PSRVTBL )malloc((size_t )ulTableLength);
if (!pServerTable) /* check if allocation failed */
{
/*--------------------------------------------------------------*/
/* handle the allocation error ... */
/*--------------------------------------------------------------*/
return (RC_FALSE); /* return to the caller */
} /* endif allocation failed */
/* write the header text */
memcpy(pServerTable->Header,
"SrvTable", sizeof(pServerTable->Header));
/* set the server table length */
pServerTable->ulTableLength = ulTableLength;
pServerTable->usServerCount = 0; /* init. the number of entries */
/* set the table entry pointer */
pServer = pServerTable->Server; /* to the first server entry */
/*-----------------------------------------------------------------*/
/* parse the server list datastream, write the table entries */
/*-----------------------------------------------------------------*/
/* set the ptr to end of data */
pDataEnd = pDataStream + ulDataLength;
/* check if eod is not reached */
while (pDataStream < pDataEnd)
{ /* check the item identifier */
switch (((PITEM )pDataStream)->id)
{ /* overcome big-endian format */
/* using macro ID() */
case ID(ID_IRS): /* server list delimiter: */
/* check if it is an end item */
if (((PITEM )pDataStream)->it == IT_END)
{
/*-----------------------------------------------------*/
/* increase number of servers, skip server table entry */
/*-----------------------------------------------------*/
pServerTable->usServerCount++;
pServer = (PSERVER )
((PCHAR )pServer + (offsetof(SERVER, Name[0])
+ pServer->usNameLength));
}
else /* server list start item: */
{
/*-----------------------------------------------------*/
/* initialize current server information */
/*-----------------------------------------------------*/
pServer->pSession = NULL;
pServer->pIndexTable = NULL;
}
break;
case ID(ID_IRSN): /* server name item: */
/*--------------------------------------------------------*/
/* set server fields: name length and name */
/*--------------------------------------------------------*/
/* overcome big-endian format using macro VAL2() */
/*--------------------------------------------------------*/
pServer->usNameLength = VAL2(&(((PITEM )pDataStream)->ll))
- offsetof(ITEM, value[0]);
/* copy name to server table */
memcpy(pServer->Name,
((PITEM )pDataStream)->value,
(size_t )pServer->usNameLength);
break;
case ID(ID_IRSL): /* server location item: */
/*--------------------------------------------------------*/
/* hold the server location in the server table */
/*--------------------------------------------------------*/
pServer->Location = (UCHAR )*((PITEM )pDataStream)->value;
break;
default:
/* skip all unknown data items */
break;
} /* endswitch item identifier */
/* skip current data item */
/*--------------------------------------------------------------*/
/* overcome big-endian format using macro VAL2() */
/*--------------------------------------------------------------*/
pDataStream += VAL2(&(((PITEM )pDataStream)->ll));
} /* endwhile not end of data */
/*-----------------------------------------------------------------*/
/* set output parameter (pointer to server table) */
/*-----------------------------------------------------------------*/
*ppServerTable = pServerTable;
return (RC_TRUE); /* return to the caller */
} /* end of ListServers */
/*=====================================================================+
| |
| Entry point: ListIndexes |
| |
| Function: Builds an index table containing |
| at most LT_NUMBER_OF_INDEXES |
| accessible information-retrieval indexes. |
| Creates and initializes for any index the |
| index information. |
| |
| Input |
| parameters: Session pointer |
| |
| Output |
| parameters: Pointer to index table |
| |
| Return codes: Status ok RC_TRUE |
| Status not ok RC_FALSE |
| |
| Input files: None |
| |
| Output files: None |
| |
| Calls: API functions: |
| |
| EhwListIndexes |
| |
| Exits: Returns to caller |
| |
|----------------------------------------------------------------------|
| |
| Program logic: |
| |
| - Determine the total size of the index table: |
| Size of index table header plus LT_NUMBER_OF_INDEXES times |
| the size of an index table pointer. |
| - Allocate the index table area. |
| - Initialize the index table header fields: |
| Header text, length of table, number of index table slots and |
| number of index entries. |
| |
| - Do until EhwListIndexes has returned the last data block |
| or there are no more slots available in the index table. |
| |
| - Issue an EhwListIndexes function call to obtain an index list |
| datastream block. |
| - If the API function indicates an error |
| - Release all storage up to now allocated by this function. |
| - Return to the caller. |
| Endif |
| |
| - Parse the index list datastream block: |
| While the end of current data block is not reached |
| |
| - Check the current item identifier: |
| If it is an index name item (ID_XNAM) |
| |
| - Create and initialize the index information: |
| - Calculate the size of index information. |
| (Reserve LT_SIZEOF_LSCE_ITEM bytes for the |
| library services DLL name datastream item). |
| - Allocate the index information area. |
| If the allocation failed |
| - Release all storage up to now allocated by |
| this function. |
| - Return to the caller. |
| Endif |
| - Initialize the index information header fields. |
| - Assign the current item length to structure field |
| 'length of detail datastream'. |
| - Copy the current index name item to the |
| index information area. |
| - Set the index name item pointer. |
| |
| - Update index table fields: |
| - Increase the index count in the index table. |
| - Save the current index information pointer. |
| |
| - If all slots of the index table are used |
| - Leave the while loop. |
| Endif |
| |
| Endif |
| |
| - Skip current item (update the data pointer). |
| |
| Endwhile |
| |
| Enddo |
| |
| - Assign the index table address to the output parameter. |
| - Return to the caller. |
| |
+=====================================================================*/
/*====================================================================*/
/* internal function ListIndexes (build an index table) */
/*====================================================================*/
INT ListIndexes /* hold the indexes in a table */
(
PVOID pSession, /* In -- session pointer */
XTBL **ppIndexTable /* Out -- index table pointer */
) /* function value: status code */
{ /* function variables: */
ULONG ulReturnCode = RC_DONE;/* API return code */
ULONG ulDiagnosisInfo = 0L; /* API diagnosis information */
ULONG ulDataLength = 0L; /* API datastream length */
PCHAR pDataStream = NULL; /* API datastream pointer */
PCHAR pDataEnd = NULL; /* end of datastream pointer */
PXTBL pIndexTable = NULL; /* pointer to index table */
PINDEX *ppIndex = NULL; /* ptr to index info. pointer */
USHORT usItemLength = 0; /* datastream item length */
/*-----------------------------------------------------------------*/
/* initialize the output parameter (pointer to index table) */
/*-----------------------------------------------------------------*/
*ppIndexTable = NULL;
/*-----------------------------------------------------------------*/
/* create an index table for at most LT_NUMBER_OF_INDEXES entries */
/* (LT_NUMBER_OF_INDEXES must be greater than zero !!!) */
/*-----------------------------------------------------------------*/
ulDataLength = (offsetof(XTBL, pIndex[0]) +
LT_NUMBER_OF_INDEXES * sizeof(pIndexTable->pIndex));
pIndexTable = (PXTBL )malloc((size_t )ulDataLength);
if (!pIndexTable) /* check if allocation failed */
{
/*--------------------------------------------------------------*/
/* handle the allocation error ... */
/*--------------------------------------------------------------*/
return (RC_FALSE); /* return to the caller */
} /* endif allocation failed */
/* write the header text */
memcpy(pIndexTable->Header,
"IndexTbl", sizeof(pIndexTable->Header));
/* set the index table length */
pIndexTable->ulTableLength = ulDataLength;
/* init. the number of slots */
pIndexTable->usIndexSlots = LT_NUMBER_OF_INDEXES;
pIndexTable->usIndexCount = 0; /* init. the number of entries */
/* set the table entry pointer */
ppIndex = pIndexTable->pIndex; /* to the first index entry */
/*-----------------------------------------------------------------*/
/* call API service EhwListIndex until end of data is indicated */
/* or the limit for number of indexes is reached */
/*-----------------------------------------------------------------*/
do
{
ulReturnCode =
EhwListIndexes (pSession, /* In -- session pointer */
&ulDataLength, /* Out -- datastream length */
&pDataStream, /* Out -- index list */
&ulDiagnosisInfo /* Out -- diagnosis info. */
);
printf ("ReturnCode (EhwListIndexes) = %d \n", ulReturnCode);
/* check the API return code */
if ((ulReturnCode != RC_DONE) &&
(ulReturnCode != RC_CONTINUATION_MODE_ENTERED))
{
/*-----------------------------------------------------------*/
/* handle the function error ... */
/*-----------------------------------------------------------*/
/* free index related storage */
while (ppIndex > pIndexTable->pIndex)
{
ppIndex--;
free(*ppIndex);
}
free(pIndexTable); /* release the index table */
return (RC_FALSE); /* return to the caller */
} /* endif API call failed */
/*--------------------------------------------------------------*/
/* parse the index list datastream, build the table entries */
/*--------------------------------------------------------------*/
/* set the ptr to end of data */
pDataEnd = pDataStream + ulDataLength;
while (pDataStream < pDataEnd) /* check if eod is not reached */
{ /* check the item identifier */
/* overcome big-endian format */
/* using macro ID() */
if (((PITEM )pDataStream)->id == ID(ID_XNAM))
{
/* index name item: */
/*--------------------------------------------------------*/
/* allocate storage for current index information */
/*--------------------------------------------------------*/
/* overcome big-endian format using macro VAL2() */
/*--------------------------------------------------------*/
/* calculate needed data size */
usItemLength = VAL2(&(((PITEM )pDataStream)->ll));
ulDataLength = (ULONG )(offsetof(INDEX, Data[0]) +
usItemLength + LT_SIZEOF_LSCE_ITEM);
/* allocate index info struct. */
*ppIndex = (PINDEX )malloc((size_t )ulDataLength);
if (!(*ppIndex)) /* check if allocation failed */
{
/*-----------------------------------------------------*/
/* handle the allocation error ... */
/*-----------------------------------------------------*/
/* free index related storage */
while (ppIndex > pIndexTable->pIndex)
{
ppIndex--;
free(*ppIndex);
}
free(pIndexTable); /* release the index table */
return (RC_FALSE); /* return to the caller */
} /* endif allocation failed */
/*--------------------------------------------------------*/
/* set or initialize the index information fields */
/*--------------------------------------------------------*/
/* write the header text */
memcpy((*ppIndex)->Header,
"IndxInfo", sizeof((*ppIndex)->Header));
(*ppIndex)->ulInfoLength = ulDataLength;
(*ppIndex)->ulHandle = 0L;
(*ppIndex)->Type = 0x00;
(*ppIndex)->Property = 0x00;
(*ppIndex)->pDLLcl = NULL;
(*ppIndex)->pDLLsrv = NULL;
(*ppIndex)->pResult = NULL;
(*ppIndex)->ulDataLength = (ULONG )usItemLength;
(*ppIndex)->pName = (PITEM )(*ppIndex)->Data;
/* copy item to index info. */
memcpy((*ppIndex)->pName,
pDataStream, (size_t )usItemLength);
/*--------------------------------------------------------*/
/* update number of indexes and index info. pointer */
/*--------------------------------------------------------*/
pIndexTable->usIndexCount++;
ppIndex++;
/*--------------------------------------------------------*/
/* check if index table is full */
/*--------------------------------------------------------*/
if (!(pIndexTable->usIndexCount
< pIndexTable->usIndexSlots)) break;
} /* endif index name item */
/* skip current data item */
/*-----------------------------------------------------------*/
/* invert USHORT item length from 'big-endian' to 'intel' */
/* format using macro VAL2() */
/*-----------------------------------------------------------*/
pDataStream += VAL2(&(((PITEM )pDataStream)->ll));
} /* endwhile not end of data */
} while ((ulReturnCode == RC_CONTINUATION_MODE_ENTERED) &&
(pIndexTable->usIndexCount < pIndexTable->usIndexSlots));
/* (pIndexTable->usIndexCount < LT_NUMBER_OF_INDEXES)); */
/*-----------------------------------------------------------------*/
/* set output parameter (pointer to index table) */
/*-----------------------------------------------------------------*/
*ppIndexTable = pIndexTable;
return (RC_TRUE); /* return to the caller */
} /* end of ListIndexes */
/*=====================================================================+
| |
| Entry point: OpenIndex |
| |
| Function: Opens an informaion-retrieval index and adds the |
| index detail information to the provided |
| index information. |
| |
| Input |
| parameters: Session pointer |
| Pointer to index table |
| |
| Output |
| parameters: Pointer to index table (possibly re-allocated) |
| |
| Return codes: Status ok RC_TRUE |
| Status not ok RC_FALSE |
| |
| Input files: None |
| |
| Output files: None |
| |
| Calls: API functions: |
| |
| EhwOpenIndex |
| EhwGetIndexInfo |
| EhwCloseIndex (if an error occurs) |
| |
| Exits: Returns to caller |
| |
|----------------------------------------------------------------------|
| |
| Program logic: |
| |
| - Access the index name datastream item pointer provided with the |
| input index information. |
| |
| - Issue an EhwOpenIndex function call to open the information- |
| retrieval index. |
| - Check the API function return code. |
| - Save the returned index handle in the index information structure. |
| |
| - Issue an EhwGetIndexInfo function call to obtain the index |
| detail information datastream. |
| - If the API function return code indicates an error |
| - Invoke the API function EhwCloseIndex to close the open index. |
| - Reset the index handle field in the index information. |
| - Set the function status code. |
| - Return to the caller. |
| Endif |
| |
| - Parse the index detail information datastream: |
| While the end of data is not yet reached |
| |
| - Select the item identifier |
| |
| - When ID_XTYP (index type item) |
| |
| - Save the index type in the index information structure. |
| |
| - When ID_LSCE (library services DLL name item) |
| |
| - Check if the LSCE item fits into the index information. |
| If not then re-allocate the index information. |
| - If the re-allocation failed |
| - Invoke the API function EhwCloseIndex. |
| - Reset the current index handle. |
| - Set the function status code. |
| - Return to the caller. |
| Endif |
| - Update information length and name item pointer. |
| - Set the output parameter (index information pointer). |
| Endif |
| - Set the pointer to LSCE (library services DLL name) item. |
| - Copy the LSCE item to the index information. |
| - Update the length of index detail datastream. |
| |
| - Otherwise - |
| |
| Endselect |
| |
| - Skip current item (update the data pointer). |
| |
| Endwhile |
| |
| - Return to the caller. |
| |
+=====================================================================*/
/*====================================================================*/
/* internal function OpenIndex (open index, complete the index info.) */
/*====================================================================*/
INT OpenIndex /* open the specified index */
(
PVOID pSession, /* In -- session pointer */
INDEX **ppIndex /* In/Out index info. (ptr) */
) /* function value: status code */
{ /* function variables: */
ULONG ulReturnCode = RC_DONE;/* API return code */
ULONG ulDiagnosisInfo = 0L; /* API diagnosis information */
ULONG ulIndexHandle = 0L; /* API index handle */
ULONG ulDataLength = 0L; /* API datastream length */
PCHAR pDataStream = NULL; /* API datastream pointer */
PCHAR pDataEnd = NULL; /* end of datastream pointer */
USHORT usItemLength = 0; /* datastream item length */
/* index information pointer */
PINDEX pIndex = *ppIndex;
CHAR Work[250];
/*-----------------------------------------------------------------*/
/* access the index name item in the index information structure */
/*-----------------------------------------------------------------*/
/* invert the item length from */
/* big-endian to intel format */
usItemLength = VAL2(&(pIndex->pName->ll));
/*-----------------------------------------------------------------*/
/* set length and pointer of index information datastream */
/*-----------------------------------------------------------------*/
ulDataLength = (ULONG )usItemLength;
pDataStream = (PCHAR )pIndex->pName;
/*-----------------------------------------------------------------*/
/* call API service to open the information retrieval index */
/*-----------------------------------------------------------------*/
ulReturnCode =
EhwOpenIndex (pSession, /* In -- session pointer */
ulDataLength, /* In -- datastream length */
pDataStream, /* In -- index list */
&ulIndexHandle, /* Out -- index handle */
&ulDiagnosisInfo); /* Out -- diagnosis info. */
printf ("ReturnCode (EhwOpenIndex) = %d \n", ulReturnCode);
if (ulReturnCode != RC_DONE) /* check the API return code */
{
/*--------------------------------------------------------------*/
/* handle the function error ... */
/*--------------------------------------------------------------*/
return (RC_FALSE); /* return to the caller */
} /* endif API call failed */
pIndex->ulHandle = ulIndexHandle; /* save the index handle */
memset(Work, 0x00, sizeof(Work));
memcpy(Work, ((PITEM )pDataStream)->value, VAL2(&(((PITEM )pDataStream)->ll)) - 5);
printf ("Index opened sucessfully = %s \n", Work);
/*-----------------------------------------------------------------*/
/* invoke API service to get the index detail information */
/* Note: not all of the items returned are parsed from the */
/* datastream */
/*-----------------------------------------------------------------*/
ulReturnCode =
EhwGetIndexInfo (pSession, /* In -- session pointer */
ulIndexHandle, /* In -- index handle */
&ulDataLength, /* Out -- datastream length */
&pDataStream, /* Out -- index list */
&ulDiagnosisInfo); /* Out -- diagnosis info. */
printf ("ReturnCode (EhwGetIndexInfo) = %d \n", ulReturnCode);
if (ulReturnCode != RC_DONE) /* check the API return code */
{
/*--------------------------------------------------------------*/
/* handle the function error ... */
/*--------------------------------------------------------------*/
ulReturnCode = /* close current index */
EhwCloseIndex (pSession, /* In -- session pointer */
ulIndexHandle, /* In -- index handle */
&ulDiagnosisInfo);/* Out -- diagnosis info. */
printf ("ReturnCode (EhwCloseIndex) = %d \n", ulReturnCode);
pIndex->ulHandle = 0L; /* reset the index handle */
return (RC_FALSE); /* return to the caller */
} /* endif API call failed */
/*-----------------------------------------------------------------*/
/* parse the index information datastream */
/*-----------------------------------------------------------------*/
/* set the ptr to end of data */
pDataEnd = pDataStream + ulDataLength;
/* check if eod is not reached */
while (pDataStream < pDataEnd)
{ /* check the item identifier */
switch (((PITEM )pDataStream)->id)
{ /* overcome big-endian format */
/* using macro ID() */
case ID(ID_XTYP): /* index type item: */
/*--------------------------------------------------------*/
/* save index type in the index information structure */
/*--------------------------------------------------------*/
pIndex->Type = (UCHAR )*((PITEM )pDataStream)->value;
break;
case ID(ID_LSCE): /* LS client DLL item: */
/*--------------------------------------------------------*/
/* check if the DLL item fits into index information */
/*--------------------------------------------------------*/
/* invert 'big-endian' item length using macro VAL2() */
/*--------------------------------------------------------*/
usItemLength = VAL2(&(((PITEM )pDataStream)->ll));
/* determine needed info. size */
ulDataLength = (offsetof(INDEX, Data[0]) +
pIndex->ulDataLength +
(ULONG )usItemLength);
if (ulDataLength > pIndex->ulInfoLength)
{
/*-----------------------------------------------------*/
/* extend (re-allocate) the index information */
/*-----------------------------------------------------*/
pIndex = (PINDEX )realloc(pIndex, (size_t )ulDataLength);
if (!pIndex) /* check if allocation failed */
{
/*--------------------------------------------------*/
/* handle the allocation error ... */
/*--------------------------------------------------*/
ulReturnCode = /* close current index */
EhwCloseIndex
(pSession, /* In -- session pointer */
ulIndexHandle, /* In -- index handle */
&ulDiagnosisInfo); /* Out -- diagnosis info. */
printf ("ReturnCode (EhwCloseIndex) = %d \n",
ulReturnCode);
/* reset the index handle */
pIndex->ulHandle = 0L;
return (RC_FALSE); /* return to the caller */
} /* endif allocation failed */
/*-----------------------------------------------------*/
/* update information length and name item pointer */
/*-----------------------------------------------------*/
pIndex->ulInfoLength = ulDataLength;
pIndex->pName = (PITEM )pIndex->Data;
/*-----------------------------------------------------*/
/* set output parameter (pointer to index information) */
/*-----------------------------------------------------*/
*ppIndex = pIndex;
}
/*--------------------------------------------------------*/
/* copy LS DLL item to index information */
/*--------------------------------------------------------*/
pIndex->pDLLcl = (PITEM )
(pIndex->Data + pIndex->ulDataLength);
memcpy(pIndex->pDLLcl,
pDataStream, (size_t )usItemLength);
/* set index datastream length */
pIndex->ulDataLength += (ULONG )usItemLength;
break;
case ID(ID_LSSE): /* LS server DLL item: */
/*--------------------------------------------------------*/
/* check if the DLL item fits into index information */
/*--------------------------------------------------------*/
/* invert 'big-endian' item length using macro VAL2() */
/*--------------------------------------------------------*/
usItemLength = VAL2(&(((PITEM )pDataStream)->ll));
/* determine needed info. size */
ulDataLength = (offsetof(INDEX, Data[0]) +
pIndex->ulDataLength +
(ULONG )usItemLength);
if (ulDataLength > pIndex->ulInfoLength)
{
/*-----------------------------------------------------*/
/* extend (re-allocate) the index information */
/*-----------------------------------------------------*/
pIndex = (PINDEX )realloc(pIndex, (size_t )ulDataLength);
if (!pIndex) /* check if allocation failed */
{
/*--------------------------------------------------*/
/* handle the allocation error ... */
/*--------------------------------------------------*/
ulReturnCode = /* close current index */
EhwCloseIndex
(pSession, /* In -- session pointer */
ulIndexHandle, /* In -- index handle */
&ulDiagnosisInfo); /* Out -- diagnosis info. */
printf ("ReturnCode (EhwCloseIndex) = %d \n",
ulReturnCode);
/* reset the index handle */
pIndex->ulHandle = 0L;
return (RC_FALSE); /* return to the caller */
} /* endif allocation failed */
/*-----------------------------------------------------*/
/* update information length and name item pointer */
/*-----------------------------------------------------*/
pIndex->ulInfoLength = ulDataLength;
pIndex->pName = (PITEM )pIndex->Data;
/*-----------------------------------------------------*/
/* set output parameter (pointer to index information) */
/*-----------------------------------------------------*/
*ppIndex = pIndex;
}
/*--------------------------------------------------------*/
/* copy LS DLL item to index information */
/*--------------------------------------------------------*/
pIndex->pDLLsrv = (PITEM ) (pIndex->Data + pIndex->ulDataLength);
memcpy(pIndex->pDLLsrv, pDataStream, (size_t )usItemLength);
/* set index datastream length */
pIndex->ulDataLength += (ULONG )usItemLength;
break;
/*------------------------------------------------------------ */
/* list of additional items to retrieve from datastream */
/*------------------------------------------------------------ */
case ID(ID_XLOC): /* index data path */
case ID(ID_WLOC): /* index work path */
case ID(ID_LIBID): /* library information (optional)*/
case ID(ID_XTADD): /* feature index type (optional) */
case ID(ID_XCCSID): /* CCSID of GTR index (optional) */
case ID(ID_XTTL): /* index title (optional) */
case ID(ID_XDESC): /* index description (optional) */
case ID(ID_CCSID): /* CCSID of title,desc(optional) */
default:
break;
} /* endswitch item identifier */
/* skip current data item */
/*--------------------------------------------------------------*/
/* invert USHORT item length from 'big-endian' to 'intel' */
/* format using macro VAL2() */
/*--------------------------------------------------------------*/
pDataStream += VAL2(&(((PITEM )pDataStream)->ll));
} /* endwhile not end of data */
return (RC_TRUE);
} /* end of OpenIndex() */
/*=====================================================================+
| |
| Entry point: ListResult |
| |
| Function: Builds a result information containing the search |
| result datastream and a specified number of |
| document item reference pointers. |
| (The number of references is limited by the |
| reference limit and the result size parameters.) |
| Removes a possibly pending result information from |
| the index information. |
| |
| Input |
| parameters: Session pointer |
| Result handle |
| Result size |
| Reference limit (maximum number of documents to be |
| referenced in the result information) |
| Index information |
| |
| Output |
| parameters: Index information |
| |
| Return codes: Status ok RC_TRUE |
| Status not ok RC_FALSE |
| |
| Input files: None |
| |
| Output files: None |
| |
| Calls: Internal functions: |
| |
| DeleteResult |
| |
| API functions: |
| |
| EhwListResult |
| |
| Exits: Returns to caller |
| |
|----------------------------------------------------------------------|
| |
| Program logic: |
| |
| - If the index information contains a pending result information |
| - Call the internal function DeleteResult to delete the 'old' |
| result information. |
| - Check the function status code. |
| Endif |
| |
| - Determine the number of document pointers using the |
| reference limit and result size parameters and calculate |
| the size of the result information. |
| - Allocate the result information area. |
| - Initialize the result information header fields. |
| - Define a work data list structure temporarily used to |
| anchor the first result list information block. |
| |
| - Do until EhwListResult has returned the last data block. |
| |
| - Issue an EhwListResult function call to obtain a result list |
| datastream block. |
| - If the API function indicates an error |
| - If at least one data list area is allocated |
| - Save the first data list area in the result information. |
| - Invoke the internal function DeleteResult to release |
| all search result related storage. |
| - Set the function status code. |
| - Return to the caller. |
| Endif |
| Endif |
| |
| - Allocate a 'new' data list area for the returned data block |
| and anchor it in the 'old' data list area (next data pointer). |
| If the allocation failed |
| - Save the first data list area in the result information. |
| - Invoke the internal function DeleteResult to release |
| all search result related storage. |
| - Set the function status code. |
| - Return to the caller. |
| Endif |
| |
| - Initialize the data list fields (next data pointer). |
| - Save length and data block in the current data list area. |
| |
| - Update the result data length field in the result information. |
| |
| Enddo |
| |
| - Anchor the first data list area in the result information. |
| - Save the result information pointer in the index information. |
| |
| - Set the document reference pointers in the result information: |
| (Parse the result list datastream starting with the first |
| anchored data list area.) |
| While the current data list is not the last one |
| |
| While the end of current data block is not reached |
| |
| - Check the current item identifier: |
| If it is a document identifier item (ID_DID) |
| |
| - Assign the current item pointer to the current |
| document reference pointer. |
| - Increase the reference counter in the result information. |
| |
| - if the document reference limit is reached |
| - Set the function status code. |
| - Return to the caller. |
| Endif |
| |
| - Update the current document reference pointer. |
| |
| Endif |
| |
| - Skip current item (update the data pointer). |
| |
| Endwhile |
| |
| - Replace current with next data list pointer. |
| |
| Endwhile |
| |
| - Return to the caller. |
| |
+=====================================================================*/
/*====================================================================*/
/* internal function ListResult (build the result information) */
/*====================================================================*/
INT ListResult /* access the result list */
(
PVOID pSession, /* In -- session pointer */
ULONG ulResultHandle, /* In -- result handle */
ULONG ulResultSize, /* In -- result size */
ULONG ulReferenceLimit, /* In -- reference limit */
PINDEX pIndex /* In/Out index information */
) /* function value: status code */
{ /* function variables: */
ULONG ulReturnCode = RC_DONE;/* API return code */
ULONG ulDiagnosisInfo = 0L; /* API diagnosis information */
ULONG ulDataLength = 0L; /* API datastream length */
PCHAR pDataStream = NULL; /* API datastream pointer */
PCHAR pDataEnd = NULL; /* end of datastream pointer */
PRESULT pResult = NULL; /* result information pointer */
PITEM *ppDocument = NULL; /* ptr to document item ptr */
LIST List; /* work data list structure */
PLIST pList = &List; /* current data list pointer */
INT iStatus = RC_TRUE;/* function status code */
UCHAR Work[250]; /* work area to print docID */
/*-----------------------------------------------------------------*/
/* release a possibly pending result information */
/* by calling the internal function DeleteResult */
/*-----------------------------------------------------------------*/
if (pIndex->pResult)
{
iStatus =
DeleteResult (pSession, /* In -- session pointer */
pIndex); /* In/Out index information */
if (iStatus != RC_TRUE) /* check DeleteResult status */
{
/*-----------------------------------------------------------*/
/* handle the function error ... */
/*-----------------------------------------------------------*/
return (iStatus); /* return to the caller */
} /* endif DeleteResult failed */
} /* endif pending result info. */
/*-----------------------------------------------------------------*/
/* determine number of document pointers in the result information */
/*-----------------------------------------------------------------*/
if (ulReferenceLimit > ulResultSize)
ulReferenceLimit = ulResultSize;
if (!ulReferenceLimit) /* check if the limit is zero */
ulReferenceLimit = 1L;
/* calculate result info. size */
ulDataLength = offsetof(RESULT, pDocument) +
ulReferenceLimit * sizeof(pResult->pDocument);
/*-----------------------------------------------------------------*/
/* allocate and initialize the result information */
/*-----------------------------------------------------------------*/
pResult = (PRESULT )malloc((size_t )ulDataLength);
if (!pResult) /* check if allocation failed */
{
/*--------------------------------------------------------------*/
/* handle the allocation error ... */
/*--------------------------------------------------------------*/
return (RC_FALSE); /* return to the caller */
} /* endif allocation failed */
/* write the header text */
memcpy(pResult->Header, "RsltInfo", sizeof(pResult->Header));
pResult->ulInfoLength = ulDataLength;
pResult->ulHandle = ulResultHandle;
pResult->ulSize = ulResultSize;
pResult->ulDataLength = 0L;
pResult->pData = NULL;
pResult->ulDocumentCount = 0L;
pResult->pDocument[0] = NULL;
/*-----------------------------------------------------------------*/
/* initialize the (temporary) first data list structure */
/*-----------------------------------------------------------------*/
memset(pList, 0x00, sizeof(List));
/*-----------------------------------------------------------------*/
/* access the result list information, by calling API service */
/* EhwListResult (until end of data is indicated) */
/*-----------------------------------------------------------------*/
do
{
ulReturnCode =
EhwListResult (pSession, /* In -- session pointer */
ulResultHandle, /* In -- result handle */
&ulDataLength, /* Out -- datastream length */
&pDataStream, /* Out -- index list */
&ulDiagnosisInfo);/* Out -- diagnosis info. */
printf ("ReturnCode (EhwListResult) = %d \n", ulReturnCode);
/* check the API return code */
if ((ulReturnCode != RC_DONE) &&
(ulReturnCode != RC_CONTINUATION_MODE_ENTERED))
{
/*-----------------------------------------------------------*/
/* handle the function error ... */
/*-----------------------------------------------------------*/
if (List.pNextData) /* check if a data list exists */
{ /* anchor present data lists */
pResult->pData = List.pNextData;
/* free result info. storage */
DeleteResult (pSession, /* In -- session pointer */
pIndex); /* In/Out index information */
}
return (RC_FALSE); /* return to the caller */
} /* endif API call failed */
/*--------------------------------------------------------------*/
/* allocate a 'new' data list area, anchor it in the 'old' one */
/*--------------------------------------------------------------*/
pList->pNextData = (PLIST )
malloc((size_t )(offsetof(LIST, Data[0])
+ ulDataLength));
/*--------------------------------------------------------------*/
/* update current data list pointer */
/*--------------------------------------------------------------*/
pList = pList->pNextData; /* replace old with new ptr */
if (!pList) /* check if allocation failed */
{
/*-----------------------------------------------------------*/
/* handle the allocation error ... */
/*-----------------------------------------------------------*/
/* anchor present data lists */
pResult->pData = List.pNextData;
/* free result info. storage */
DeleteResult (pSession, /* In -- session pointer */
pIndex); /* In/Out index information */
return (RC_FALSE); /* return to the caller */
} /* endif allocation failed */
/*--------------------------------------------------------------*/
/* save current result list block in the list data area */
/*--------------------------------------------------------------*/
pList->pNextData = NULL;
pList->ulDataLength = ulDataLength;
memcpy(pList->Data, pDataStream, (size_t )ulDataLength);
/*--------------------------------------------------------------*/
/* update total result list data length */
/*--------------------------------------------------------------*/
pResult->ulDataLength += ulDataLength;
} while (ulReturnCode == RC_CONTINUATION_MODE_ENTERED);
/*-----------------------------------------------------------------*/
/* anchor first data list area in the result information */
/*-----------------------------------------------------------------*/
pResult->pData = List.pNextData;
/*-----------------------------------------------------------------*/
/* save current result information in the index information */
/*-----------------------------------------------------------------*/
pIndex->pResult = pResult;
/*-----------------------------------------------------------------*/
/* set the document pointers (references) in the */
/* result information by parsing the chained result list data */
/*-----------------------------------------------------------------*/
if (!ulReferenceLimit) /* check the reference limit */
return (RC_TRUE);
ppDocument = pResult->pDocument; /* start at first document ptr */
pList = pResult->pData; /* reset current data list ptr */
while (pList) /* check if end of total */
{ /* result list data is reached */
ulDataLength = pList->ulDataLength;
pDataStream = (PCHAR )pList->Data;
/* set the ptr to end of block */
pDataEnd = pDataStream + ulDataLength;
/*--------------------------------------------------------------*/
/* parse current result list block until end of data (block) */
/* or the document reference limit is reached */
/*--------------------------------------------------------------*/
while (pDataStream < pDataEnd)
{ /* check the item identifier */
/* overcome big-endian format */
/* using macro ID() */
if (((PITEM )pDataStream)->id == ID(ID_DID))
{
/* document identifier item: */
/*--------------------------------------------------------*/
/* save address of current document identifier item */
/* increase counter in the result information structure */
/*--------------------------------------------------------*/
*ppDocument = (PITEM )pDataStream;
pResult->ulDocumentCount++;
memset(Work, 0x00, sizeof(Work));
memcpy(Work, ((PITEM )pDataStream)->value,
VAL2(&(((PITEM )pDataStream)->ll)) - 5);
printf ("Document ID = %s \n", Work);
/*--------------------------------------------------------*/
/* check if the document reference limit is reached */
/*--------------------------------------------------------*/
if (!(pResult->ulDocumentCount < ulReferenceLimit))
return (RC_TRUE); /* return to the caller */
/*--------------------------------------------------------*/
/* skip current document item pointer (reference) */
/*--------------------------------------------------------*/
ppDocument++;
} /* endif document id item */
/* skip current data item */
/*-----------------------------------------------------------*/
/* invert 'big-endian' to 'intel' format using macro VAL2() */
/*-----------------------------------------------------------*/
pDataStream += VAL2(&(((PITEM )pDataStream)->ll));
} /* endwhile not end of list */
pList = pList->pNextData; /* skip current data list */
} /* endwhile not end of result */
return (RC_TRUE);
} /* end of ListResult() */
/*=====================================================================+
| |
| Entry point: DeleteResult |
| |
| Function: Deletes the result information the provided |
| index information refers to. |
| |
| Input |
| parameters: Session pointer |
| Index information |
| |
| Output |
| parameters: Index information |
| |
| Return codes: Status ok RC_TRUE |
| Status not ok RC_FALSE |
| |
| Input files: None |
| |
| Output files: None |
| |
| |
| Calls: API functions: |
| |
| EhwDeleteResult |
| |
| Exits: Returns to caller |
| |
|----------------------------------------------------------------------|
| |
| Program logic: |
| |
| - If the index information contains a pending result information |
| - Access the result handle. |
| if it is a valid API handle (not equal to zero) |
| - Issue an EhwDeleteResult function call to delete the |
| current search result. |
| - Check the API function return code. |
| Endif |
| |
| - Free the result datastream (chained data list areas). |
| |
| - Release the current result information area. |
| |
| - Reset the result information pointer in the index information. |
| |
| Endif |
| |
| - Return to the caller. |
| |
+=====================================================================*/
/*====================================================================*/
/* internal function DeleteResult (release the result information) */
/*====================================================================*/
INT DeleteResult /* delete current result info. */
(
PVOID pSession, /* In -- session pointer */
PINDEX pIndex /* In/Out index information */
) /* function value: status code */
{ /* function variables: */
ULONG ulReturnCode = RC_DONE;/* API return code */
ULONG ulResultHandle = 0L; /* API result handle */
ULONG ulDiagnosisInfo = 0L; /* API diagnosis information */
INT iStatus = RC_TRUE;/* work data list structure */
PLIST pList = NULL; /* current data list pointer */
PLIST pNext = NULL; /* next data list pointer */
/* result information pointer */
PRESULT pResult = pIndex->pResult;
/*-----------------------------------------------------------------*/
/* check if there is a pending result information */
/*-----------------------------------------------------------------*/
if (!pResult) return (RC_TRUE); /* return to the caller */
ulResultHandle = pResult->ulHandle; /* access the result handle */
/*-----------------------------------------------------------------*/
/* if applicable, release current API search result */
/* by calling API service EhwDeleteResult */
/*-----------------------------------------------------------------*/
if (ulResultHandle) /* check current result handle */
{
ulReturnCode =
EhwDeleteResult (pSession, /* In -- session pointer */
ulResultHandle, /* In -- result handle */
&ulDiagnosisInfo/* Out -- diagnosis info */
);
printf ("ReturnCode (EhwDeleteResult) = %d \n", ulReturnCode);
if (ulReturnCode != RC_DONE) /* check the API return code */
{
/*-----------------------------------------------------------*/
/* handle the function error ... */
/*-----------------------------------------------------------*/
iStatus = RC_FALSE; /* set function status code */
} /* endif API function failed */
} /* endif pending result info. */
/*-----------------------------------------------------------------*/
/* free the result datastream anchored in the result information */
/*-----------------------------------------------------------------*/
pList = pResult->pData; /* set first data list pointer */
while (pList) /* while not end of data lists */
{
pNext = pList->pNextData; /* save next data list pointer */
free(pList); /* release current data list */
pList = pNext; /* update pointer to data list */
} /* endwhile data list exists */
/*-----------------------------------------------------------------*/
/* release current result information area */
/*-----------------------------------------------------------------*/
free(pResult);
/*-----------------------------------------------------------------*/
/* update result information pointer in the index information */
/*-----------------------------------------------------------------*/
pIndex->pResult = NULL;
return (iStatus); /* return to the caller */
} /* end of DeleteResult() */
/*=====================================================================+
| |
| Entry point: HandleError |
| |
| Function: Error function of the sample main routine. |
| Releases the storage acquired by the sample |
| application program and ends pending sessions. |
| |
| Input |
| parameters: Pointer to server table |
| Pointer to work area |
| |
| Output |
| parameters: None |
| |
| Return codes: None |
| |
| Input files: None |
| |
| Output files: None |
| |
| |
| Calls: API functions: |
| |
| EhwEndSession |
| |
| Exits: Returns to caller |
| |
|----------------------------------------------------------------------|
| |
| Program logic: |
| |
| - If the server table exists |
| |
| - Do for all server information entries: |
| |
| - If there is a pending session |
| |
| - Issue an EhwEndSession function call to terminate the |
| session with the current server. |
| |
| Endif |
| |
| - If the index table exists |
| |
| - Do for all index information entries: |
| |
| - Release all anchored result information data. |
| - Free the current index information. |
| |
| Enddo |
| |
| - Release the index table. |
| |
| Endif |
| |
| Enddo |
| |
| - Release the server table. |
| |
| Endif |
| |
| - Free the work area. |
| |
| - Return to the caller. |
| |
+=====================================================================*/
/*====================================================================*/
/* internal error function HandleError (release allocated storage) */
/*====================================================================*/
VOID HandleError /* clear up function for main */
(
PSRVTBL pServerTable, /* In -- server table pointer */
PCHAR pArea /* In -- work area pointer */
) /* function value: none */
{ /* function variables: */
ULONG ulReturnCode = RC_DONE;/* API return code */
ULONG ulDiagnosisInfo = 0L; /* API diagnosis information */
PVOID pSession = NULL; /* API session pointer */
PXTBL pIndexTable = NULL; /* index table pointer */
PSERVER pServer = NULL; /* server information pointer */
PINDEX pIndex = NULL; /* index information pointer */
PRESULT pResult = NULL; /* result information pointer */
PLIST pList = NULL; /* data list pointer */
PLIST pNext = NULL; /* data list pointer */
/*-----------------------------------------------------------------*/
/* release storage allocated outside a session */
/*-----------------------------------------------------------------*/
if (pServerTable) /* check the server table ptr */
{
pServer = pServerTable->Server; /* initialize server info. ptr */
while (pServerTable->usServerCount)
{
/*-----------------------------------------------------------*/
/* free session related storage allocated by API functions */
/*-----------------------------------------------------------*/
pSession = pServer->pSession; /* set first session pointer */
if (pSession) /* check if session is started */
{ /* end the API session */
ulReturnCode =
EhwEndSession (pSession, /* In -- session pointer */
/* Out -- diagnosis info */
&ulDiagnosisInfo);
printf ("ReturnCode (EhwEndSession) = %d \n",
ulReturnCode);
}
/*-----------------------------------------------------------*/
/* free session related storage acquired by sample functions */
/*-----------------------------------------------------------*/
pIndexTable = pServer->pIndexTable;
if (pIndexTable) /* check if index table exists */
{ /* set ptr to first index info.*/
pIndex = pIndexTable->pIndex[0];
while (pIndexTable->usIndexCount)
{ /* set result information ptr */
pResult = pIndex->pResult;
if (pResult) /* check result info. pointer */
{ /* set first data list pointer */
pList = pResult->pData;
while (pList) /* while not end of data lists */
{ /* save next data list pointer */
pNext = pList->pNextData;
free(pList); /* release current data list */
pList = pNext; /* update pointer to data list */
} /* endwhile data list exists */
free(pResult); /* free result information */
}
free(pIndex); /* release current index info. */
pIndex++; /* update index info. pointer */
(pIndexTable->usIndexCount)--;
}
free(pIndexTable); /* release the index table */
}
/* update server info. pointer */
pServer = (PSERVER )
((PCHAR )pServer + (offsetof(SERVER, Name[0])
+ pServer->usNameLength));
(pServerTable->usServerCount)--;
}
free(pServerTable); /* release the server table */
}
if (pArea) free(pArea); /* release the work area */
return; /* return to the caller */
} /* end of HandleError() */
/*=====================================================================+
| |
| Entry point: WriteDataStream |
| |
| Function: Writes a specified datastream item to the provided |
| area. |
| |
| It is checked, if the item fits into the remaining |
| buffer space (if yes, the length of the remaining |
| space and corresponding pointer are updated). |
| |
| Conversion of USHORT variables between 'intel' and |
| 'big-endian' formats is done within this function |
| for two-byte identifiers and lengths using VAL2 |
| macro. The item values are written as provided. |
| Input |
| parameters: - Item identifier |
| - Item type |
| - Length of item value (may be zero) |
| - Item value (optional) |
| - Length of remaining space |
| - Pointer to remaining space |
| Output |
| parameters: - Updated length of remaining space (for RC_TRUE) |
| - Updated pointer to remaining space (for RC_TRUE) |
| |
| Return codes: Check ok RC_TRUE |
| Check not ok RC_FALSE |
| |
| Exits: Returns to caller. |
| |
+=====================================================================*/
/*====================================================================*/
/* internal function WriteDataItem (write datastream item) */
/*====================================================================*/
INT WriteDataItem
(
USHORT usItemId, /* In -- item identifier */
UCHAR ItemType, /* In -- item type */
USHORT usValueLength, /* In -- length of item value */
PCHAR pValue, /* In -- ptr to item value */
PULONG pulAreaLength, /* In/Out remaining area size */
PPCHAR ppArea /* In/Out ptr to target area */
)
{
USHORT usItemLL; /* total length of data item */
PITEM pItem; /* pointer to data stream item */
pItem = (PITEM )*ppArea; /* set pointer to target area */
/* calculate total item length */
usItemLL = offsetof(ITEM, value[0]) + usValueLength;
/* check remaining area length */
if ((ULONG )usItemLL > *pulAreaLength) return (RC_FALSE);
/* write item ll/id/it to area */
pItem->ll = VAL2(&usItemLL); /* invertion to big-endian */
pItem->id = VAL2(&usItemId); /* format using macro VAL2() */
pItem->it = ItemType;
/* if provided, write */
if (usValueLength) /* item value to target area */
memcpy(pItem->value, pValue, (size_t )usValueLength);
*ppArea += usItemLL; /* update current area pointer */
*pulAreaLength -= usItemLL; /* update remaining area len. */
return (RC_TRUE);
} /* end of WriteDataItem() */
/*====================================================================*/