home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / samtexco.zip / imlsmp02.c < prev    next >
Text File  |  2000-03-31  |  159KB  |  2,612 lines

  1. /*====================================================================*/
  2. /*                                                                    */
  3. /*  IBM Text Search API Sample Application Program                    */
  4. /*                                                                    */
  5. /*====================================================================*/
  6. /*                                                                    */
  7. /*  Name:               IMLSMP02.C                                     */
  8. /*  -----                                                             */
  9. /*                                                                    */
  10. /*  COPYRIGHT:                                                        */
  11. /*  ----------                                                        */
  12. /*   Digital Library Version 2 - 5648-A08.                            */
  13. /*   (C) Copyright IBM Corp. 1996.                                    */
  14. /*       All Rights Reserved                                          */
  15. /*   US Government Users Restricted Rights                            */
  16. /*   Use, duplication or disclosure restricted                        */
  17. /*        by GSA ADP Schedule                                         */
  18. /*   Contract with IBM Corp.                                          */
  19. /*   Licensed Materials - Property of IBM                             */
  20. /*                                                                    */
  21. /*  DISCLAIMER OF WARRANTIES:                                         */
  22. /*  -------------------------                                         */
  23. /*   The following [enclosed] code is sample code created by IBM      */
  24. /*   Corporation. This sample code is not part of any standard IBM    */
  25. /*   product and is provided to you solely for the purpose of         */
  26. /*   assisting you in the development of your applications.           */
  27. /*   The code is provided "AS IS", without warranty of any kind.      */
  28. /*   IBM shall not be liable for any damages arising out of your      */
  29. /*   use of the sample code, even if they have been advised of the    */
  30. /*   possibility of such damages.                                     */
  31. /*                                                                    */
  32. /*====================================================================*/
  33.  
  34. /*====================================================================*/
  35. /*  IMLSMP02.c  (API Sample Application Program 2)                     */
  36. /*====================================================================*/
  37.  
  38. /*=====================================================================+
  39. |                                                                      |
  40. | Title:        IBM Text Search Sample Application Program             |
  41. |                                                                      |
  42. | Purpose:      Template for a C application program that uses the     |
  43. |               IBM Text Search Application Program Interface.         |
  44. |                                                                      |
  45. |               The IBM Text Search Sample Application Program         |
  46. |               has to be considered as an appendix document to the    |
  47. |               IBM Text Search Application Program Interface          |
  48. |               Guide and Reference (SH12-6317-00)                     |
  49. |               rather than as a complete application to be run on     |
  50. |               your work station.                                     |
  51. |                                                                      |
  52. |               The program shows                                      |
  53. |               - the natural sequence of API function calls           |
  54. |                 during cross-index search                            |
  55. |               - the natural sequence of API function calls           |
  56. |                 if the result should be ranked                       |
  57. |               - how to intercept the API function return codes       |
  58. |               - how to build datastream input for API functions      |
  59. |               - how to parse datastream output from API functions    |
  60. |               - how to use the macros VAL2 and ID                    |
  61. |                                                                      |
  62. | Operation:    - Builds a server list containing all Text Search      |
  63. |                 servers that can be connected to the application     |
  64. |               - Starts a session with one of the servers from the    |
  65. |                 server list                                          |
  66. |               - Lists all information retrieval indexes that         |
  67. |                 can be accessed from the current session in an       |
  68. |                 index table                                          |
  69. |               - Opens the first three indexes contained in the       |
  70. |                 index table and adds corresponding index             |
  71. |                 information to the index table                       |
  72. |               - Builds a query datastream with option RANK and       |
  73. |                 issues a search request.                             |
  74. |               - If there are documents found:                        |
  75. |                 - Ranks the result                                   |
  76. |                 - Obtains the result information and anchors it      |
  77. |                   in the index table structure                       |
  78. |                 - Selects the result for just one index              |
  79. |                 - Sorts the result according to the rank value       |
  80. |                   in descending order                                |
  81. |                 - Deletes the search result lists                    |
  82. |                 - Deletes the current search result                  |
  83. |               - Deletes the index group                              |
  84. |               - Closes all current information-retrieval indexes     |
  85. |               - Ends the current information-retrieval session       |
  86. |                                                                      |
  87. |               API function calls:                                    |
  88. |                                                                      |
  89. |                   EhwListServers                                     |
  90. |                   EhwStartSession                                    |
  91. |                   EhwListIndexes                                     |
  92. |                   EhwOpenIndex                                       |
  93. |                   EhwGetIndexInfo                                    |
  94. |                   EhwCreateIndexGroup                                |
  95. |                   EhwSearch                                          |
  96. |                   EhwGetProblemInfo                                  |
  97. |                   EhwRank                                            |
  98. |                   EhwCreateResultList                                |
  99. |                   EhwGetResultList                                   |
  100. |                   EhwSelectResultList                                |
  101. |                   EhwSort                                            |
  102. |                   EhwDeleteResult                                    |
  103. |                   EhwDeleteIndexGroup                                |
  104. |                   EhwCloseIndex                                      |
  105. |                   EhwEndSession                                      |
  106. |                                                                      |
  107. | Notes:        The program is designed to handle parallel             |
  108. |               sessions with multiple open indexes.                   |
  109. |                                                                      |
  110. | Dependencies:                                                        |
  111. |                                                                      |
  112. |                                                                      |
  113. +=====================================================================*/
  114.  
  115. /*=====================================================================+
  116. |                                                                      |
  117. | Entry point:  main                                                   |
  118. |                                                                      |
  119. | Function:     Demonstrates how a C application program can use the   |
  120. |               IBM Text Search     Application Program Interface.     |
  121. | Input                                                                |
  122. | parameters:   None                                                   |
  123. |                                                                      |
  124. | Output                                                               |
  125. | parameters:   None                                                   |
  126. |                                                                      |
  127. | Return codes: Status ok         RC_TRUE                              |
  128. |               Status not ok     RC_FALSE                             |
  129. |                                                                      |
  130. | Input files:  None                                                   |
  131. |                                                                      |
  132. | Output files: None                                                   |
  133. |                                                                      |
  134. | Calls:        Internal functions:                                    |
  135. |                                                                      |
  136. |                   WriteDataStream                                    |
  137. |                   ListServers                                        |
  138. |                   ListIndexes                                        |
  139. |                   OpenIndex                                          |
  140. |                   GetProblemInfo                                     |
  141. |                   ListResult                                         |
  142. |                   DeleteResults                                      |
  143. |                   HandleExit                                         |
  144. |                                                                      |
  145. |               API functions:                                         |
  146. |                                                                      |
  147. |                   EhwStartSession                                    |
  148. |                   EhwCreateIndexGroup                                |
  149. |                   EhwSearch                                          |
  150. |                   EhwRank                                            |
  151. |                   EhwCreateResultList                                |
  152. |                   EhwSelectResultList                                |
  153. |                   EhwSort                                            |
  154. |                   EhwDeleteIndexGroup                                |
  155. |                   EhwDeleteResult                                    |
  156. |                   EhwCloseIndex                                      |
  157. |                   EhwEndSession                                      |
  158. |                                                                      |
  159. | Exits:        Returns to caller                                      |
  160. |                                                                      |
  161. |----------------------------------------------------------------------|
  162. |                                                                      |
  163. | Program logic:                                                       |
  164. |                                                                      |
  165. | - Allocate a work area used to hold API datastreams.                 |
  166. |                                                                      |
  167. | - Call the internal function ListServers to build a server list      |
  168. |   containing all Text Search   servers that can be connected to      |
  169. |   the application.                                                   |
  170. | - Check the function status code.                                    |
  171. |                                                                      |
  172. | - Select one server name from the server table.                      |
  173. | - Write the session information datastream to a work area using      |
  174. |   the internal function WriteDataItem.                               |
  175. | - Invoke the API function EhwStartSession to connect                 |
  176. |   to the selected server and to start a session.                     |
  177. | - Check the API function return code.                                |
  178. |                                                                      |
  179. | - Call the internal function ListIndexes to build an index table     |
  180. |   and to create index information for any index entry.               |
  181. | - Check the function status code.                                    |
  182. |                                                                      |
  183. | - Select index names from the index table.                           |
  184. | - Invoke the internal function OpenIndex to open the selected        |
  185. |   indexes and to complete the index information for each index.      |
  186. | - Check the function status code.                                    |
  187. |                                                                      |
  188. | - Build a query datastream using function WriteDataItem.             |
  189. | - Issue an EhwSearch API function call to process the query.         |
  190. | - Check the API function return code.                                |
  191. |                                                                      |
  192. | - If the result size is greater than zero                            |
  193. |    - Call API function EhwCreateResultList to get a handle           |
  194. |      of the result object.                                           |
  195. |    - Check the function return code.                                 |
  196. |    - Call API function EhwRank to rank the result list.              |
  197. |    - Check the function return code.                                 |
  198. |    - Call the internal function ListResult to build the              |
  199. |      result information for the current ranked result list           |
  200. |      and to anchor it in the index list.                             |
  201. |    - Check the function status code.                                 |
  202. |    - Reduce your view of the result list:                            |
  203. |      select result information for the first index only by           |
  204. |      calling API function EhwSelectResultList.                       |
  205. |    - Check the function return code.                                 |
  206. |    - Sort this result list by rank value in descending order:        |
  207. |      call API function EhwSort.                                      |
  208. |    - Check the function return code.                                 |
  209. |    - Call the internal function ListResult to get the                |
  210. |      sorted result list.                                             |
  211. |    - Check the function status code.                                 |
  212. |                                                                      |
  213. |    To end search processing:                                         |
  214. |                                                                      |
  215. |    - Invoke the internal function DeleteResults to release           |
  216. |      the result information.                                         |
  217. |    - Check the function status code.                                 |
  218. |                                                                      |
  219. | - Issue an EhwDeleteIndexGroup function call to delete               |
  220. |   the index group.                                                   |
  221. | - Check the API function return code.                                |
  222. | - Close all open indexes by calling API function EhwCloseIndex.      |
  223. |                                                                      |
  224. | - Issue an EhwEndSession function call to end the current session.   |
  225. | - Check the API function return code.                                |
  226. |                                                                      |
  227. | - Terminate search processing by calling the internal function       |
  228. |   HandleExit where allocated memory is freed.                        |
  229. |                                                                      |
  230. | - Return to the caller.                                              |
  231. |                                                                      |
  232. +=====================================================================*/
  233.  
  234.  
  235. #if defined (__WINDOWS__)
  236. #include <windows.h>
  237. #define __WINDOWS_H 1
  238. #endif
  239.  
  240. /*--------------------------------------------------------------------*/
  241. /*  external definitions                                              */
  242. /*--------------------------------------------------------------------*/
  243. #include <stdio.h>                     /* => printf ()                */
  244. #include <stdlib.h>                    /* standard library functions  */
  245. #include <string.h>                    /* string handling functions   */
  246.  
  247. #include <imoapic.h>                   /* API definitions for C       */
  248. #if defined (__UNIX__)
  249. #include "ehwlsgvi.h"
  250. #include <time.h>
  251. #endif
  252.  
  253. /*--------------------------------------------------------------------*/
  254. /*  internal definitions                                              */
  255. /*--------------------------------------------------------------------*/
  256. #include <imlsmp02.h>                  /* API sample definitions      */
  257.  
  258. #ifdef  __cplusplus
  259. extern "C"
  260. {
  261. #endif
  262.  
  263. #ifdef  __cplusplus
  264. }
  265. #endif
  266. /*====================================================================*/
  267. /*  main function (IMLSMP02.c)                                         */
  268. /*====================================================================*/
  269. INT    main                            /* Sample Application Program  */
  270.        (
  271.         INT argc, PCHAR argv[], PCHAR envp[]
  272.        )                               /* function value: status code */
  273. {                                      /* function variables:         */
  274.    ULONG     ulReturnCode    = RC_DONE;/* API return code             */
  275.    ULONG     ulDiagnosisInfo = 0L;     /* API diagnosis information   */
  276.    ULONG     ulIndexHandle   = 0L;     /* API index handle            */
  277.    ULONG     ulGroupHandle   = 0L;     /* API index group handle      */
  278.    ULONG     ulResultHandle  = 0L;     /* API result handle           */
  279.    ULONG     ulResultHandle2 = 0L;     /* API result handle from      */
  280.                                        /*     EhwCreateResultList     */
  281.    ULONG     ulResultHandle3 = 0L;     /* API result handle from      */
  282.                                        /*     EhwSelectResultList     */
  283.    ULONG     ulResultSize    = 0L;     /* API result size             */
  284.    ULONG     ulResListSize   = 0L;     /* API result list size        */
  285.    ULONG     ulDataLength    = 0L;     /* API datastream length       */
  286.    PCHAR     pDataStream     = NULL;   /* API datastream pointer      */
  287.    PVOID     pSession        = NULL;   /* API session pointer         */
  288.  
  289.    USHORT    usValue         = 0;      /* USHORT datastream value     */
  290.    USHORT    iCount          = 0;      /* loop variable               */
  291.    INT       iStatus         = RC_TRUE;/* WriteDataItem() status code */
  292.  
  293.    PCHAR     pArea           = NULL;   /* pointer to work area        */
  294.  
  295.    PSRVTBL   pServerTable    = NULL;   /* pointer to server table     */
  296.    PSERVER   pServer         = NULL;   /* server table entry pointer  */
  297.  
  298.    PXTBL     pIndexTable     = NULL;   /* pointer to index table      */
  299.    PHTBL     pGroupTable     = NULL;   /* pointer to index group table*/
  300.    PPINDEX   ppIndex         = NULL;   /* ptr to index info. pointer  */
  301.    PINDEX    pIndex[10];               /* index information pointer   */
  302.    ULONG     *pulIndexHandle = NULL;   /* API index handle            */
  303.    PCHAR     pIndexName      = NULL;
  304.    PPBLTBL   pIndexProblem   = NULL;
  305.    USHORT    IndexNameLen;
  306.    UCHAR     attribute;
  307.    CHAR      work[20];
  308.    UCHAR     word1[50];
  309.    UCHAR     word2[50];
  310.    /*-----------------------------------------------------------------*/
  311.    /* initialization / processing                                     */
  312.    /*-----------------------------------------------------------------*/
  313.    memset(pIndex, 0x00, sizeof(pIndex));
  314.    memset(work,   0x00, sizeof(work));
  315.    memset(word1,   0x00, sizeof(word1));
  316.    memset(word2,   0x00, sizeof(word2));
  317.  
  318.    //---------------------------------------------------------
  319.    // only words entered in the cmd line are searched for
  320.    //---------------------------------------------------------
  321.    if(argc >1)
  322.       strcpy(word1, argv[1]);
  323.    else
  324.       strcpy(word1, QUERY_WORD01);
  325.  
  326.    if(argc >2)
  327.       strcpy(word2, argv[2]);
  328.    else
  329.       strcpy(word2, QUERY_WORD02);
  330.  
  331.    printf( " search term1  = %s \n", word1);
  332.    printf( " search term2  = %s \n", word2);
  333.    /*-----------------------------------------------------------------*/
  334.    /* allocate a work area to hold datastream information             */
  335.    /*-----------------------------------------------------------------*/
  336.    pArea = malloc(SIZEOF_DATA_AREA);   /* allocate the work area      */
  337.    if (!pArea)                         /* check if allocation failed  */
  338.    {
  339.       /*--------------------------------------------------------------*/
  340.       /* handle the allocation error ...                              */
  341.       /*--------------------------------------------------------------*/
  342.       return (RC_FALSE);               /* return to the caller        */
  343.    }                                   /* end if allocation failed    */
  344.  
  345.    /*-----------------------------------------------------------------*/
  346.    /* get a list of all SM servers that are known on your client      */
  347.    /* call function ListServers to build a server table               */
  348.    /*-----------------------------------------------------------------*/
  349.    iStatus = ListServers (&pServerTable);
  350.    if (iStatus != RC_TRUE)             /* check ListServers status    */
  351.    {
  352.       /*--------------------------------------------------------------*/
  353.       /* handle the function error ...                                */
  354.       /*--------------------------------------------------------------*/
  355.       free(pArea);                     /* release the work area       */
  356.       return (iStatus);                /* return to the caller        */
  357.    }                                   /* endif ListServers failed    */
  358.  
  359.    /*-----------------------------------------------------------------*/
  360.    /* select an information-retrieval server:                         */
  361.    /* - either the first server of the server table that complies     */
  362.    /*   with the server location specification (SESSION_IRSL)         */
  363.    /* - or the last server of the server table                        */
  364.    /*-----------------------------------------------------------------*/
  365.    pServer = pServerTable->Server;     /* set server table entry ptr  */
  366.    for (iCount = (pServerTable->usServerCount) - 1; iCount > 0; iCount--)
  367.    {
  368.       if (pServer->Location == SESSION_IRSL)  break;
  369.  
  370.       pServer = (PSERVER )((PCHAR )pServer + (offsetof(SERV, Name[0])
  371.                                               + pServer->usNameLength));
  372.    }
  373.    /*-----------------------------------------------------------------*/
  374.    /* write the session information datastream to the work area       */
  375.    /*-----------------------------------------------------------------*/
  376.    ulDataLength = SIZEOF_DATA_AREA;    /* initialize remaining length */
  377.    pDataStream  = pArea;               /* initialize target pointer   */
  378.                                        /* write IRSN item             */
  379.    iStatus = WriteDataItem (ID_IRSN, IT_ATOMIC,
  380.                             pServer->usNameLength,
  381.                             (PCHAR )pServer->Name,
  382.                             &ulDataLength, &pDataStream);
  383.  
  384.    if (iStatus != RC_TRUE)             /* check WriteDataItem status  */
  385.    {                                   /* area is too small to hold   */
  386.                                        /* the session information     */
  387.       /*--------------------------------------------------------------*/
  388.       /* handle the function error ...                                */
  389.       /*--------------------------------------------------------------*/
  390.       free(pServerTable);              /* release the server table    */
  391.       free(pArea);                     /* release the work area       */
  392.       return (iStatus);                /* return to the caller        */
  393.    }
  394.                                        /* set length of session info. */
  395.    ulDataLength = (ULONG )(pDataStream - pArea);
  396.    pDataStream  = pArea;               /* set pointer to datastream   */
  397.    memcpy(work, pServer->Name, pServer->usNameLength);
  398.    /*-----------------------------------------------------------------*/
  399.    /* Start a session, using API service EhwStartSession              */
  400.    /*-----------------------------------------------------------------*/
  401.    ulReturnCode =
  402.    EhwStartSession (ulDataLength,      /* In  -- datastream length    */
  403.                     pDataStream,       /* In  -- session information  */
  404.                     &pSession,         /* Out -- session pointer      */
  405.                     &ulDiagnosisInfo); /* Out -- diagnosis info.      */
  406.  
  407.    printf ("ReturnCode (EhwStartSession)     = %d \n", ulReturnCode);
  408.  
  409.    if (ulReturnCode != RC_DONE)        /* check the API return code   */
  410.    {
  411.       /*--------------------------------------------------------------*/
  412.       /* handle the function error ...                                */
  413.       /*--------------------------------------------------------------*/
  414.       free(pServerTable);              /* release the server table    */
  415.       free(pArea);                     /* release the work area       */
  416.       printf("Start Session failed for Text Search server %s \n", work);
  417.       return (RC_FALSE);               /* return to the caller        */
  418.    }                                   /* endif API call failed       */
  419.  
  420.    printf("Start Session successful for Text Search server %s \n", work);
  421.    /*-----------------------------------------------------------------*/
  422.    /* save the session pointer in the current server information      */
  423.    /*-----------------------------------------------------------------*/
  424.    pServer->pSession = pSession;
  425.  
  426.    /*-----------------------------------------------------------------*/
  427.    /* create an index table that holds the accessible information of  */
  428.    /* retrieval indexes (at most LT_NUMBER_OF_INDEXES entries) by     */
  429.    /* invoking the function ListIndexes                               */
  430.    /*-----------------------------------------------------------------*/
  431.    iStatus = ListIndexes (pSession,    /* In  -- session pointer      */
  432.                           &pIndexTable /* In/Out index table pointer  */
  433.                          );
  434.    if (iStatus != RC_TRUE)             /* check ListServers status    */
  435.    {                                   /* server table is not built   */
  436.       /*--------------------------------------------------------------*/
  437.       /* handle the function error ...                                */
  438.       /*--------------------------------------------------------------*/
  439.       HandleExit (pServerTable,        /* In  -- server table pointer */
  440.                    pArea);             /* In  -- work area pointer    */
  441.       return (iStatus);                /* return to the caller        */
  442.    }                                   /* endif ListIndexes failed    */
  443.  
  444.    /*-----------------------------------------------------------------*/
  445.    /* save the index table in the current server information          */
  446.    /*-----------------------------------------------------------------*/
  447.    pServer->pIndexTable = pIndexTable;
  448.  
  449.    /*-----------------------------------------------------------------*/
  450.    /* create an index group table for LT_NUMBER_OF_INDEXES entries    */
  451.    /* (LT_NUMBER_OF_INDEXES must be greater than zero )               */
  452.    /*-----------------------------------------------------------------*/
  453.    ulDataLength = (offsetof(HTBL, ulHandle[0]) +
  454.                   LT_NUMBER_OF_INDEXES * sizeof(pGroupTable->ulHandle));
  455.    pGroupTable = (PHTBL )malloc((size_t )ulDataLength);
  456.    if (!pGroupTable)                   /* check if allocation failed  */
  457.    {
  458.       /*--------------------------------------------------------------*/
  459.       /* handle the allocation error ...                              */
  460.       /*--------------------------------------------------------------*/
  461.       HandleExit (pServerTable,        /* In  -- server table pointer */
  462.                   pArea);              /* In  -- work area pointer    */
  463.       return (RC_FALSE);               /* return to the caller        */
  464.    }                                   /* endif allocation failed     */
  465.                                        /* write the header text       */
  466.    /*-----------------------------------------------------------------*/
  467.    /* save the index group table in the current server information    */
  468.    /*-----------------------------------------------------------------*/
  469.    pServer->pGroupTable = pGroupTable;
  470.  
  471.    memcpy(pGroupTable->Header,
  472.           "GroupTbl", sizeof(pGroupTable->Header));
  473.                                        /* set the index table length  */
  474.    pGroupTable->ulTableLength = ulDataLength;
  475.                                        /* init. the number of slots   */
  476.    pGroupTable->usHandleSlots = LT_NUMBER_OF_INDEXES;
  477.    pGroupTable->usHandleCount = 0;     /* init. the number of entries */
  478.                                        /* set the table entry pointer */
  479.    pulIndexHandle = pGroupTable->ulHandle;/* to the first index entry */
  480.  
  481.    /*-----------------------------------------------------------------*/
  482.    /* select the first three index information entries in the index   */
  483.    /* table in order to build an IndexGroup on which to search        */
  484.    /*-----------------------------------------------------------------*/
  485.    iCount =   pIndexTable->usIndexCount;
  486.    for(iCount = 0; iCount < pIndexTable->usIndexCount; iCount++ )
  487.    {
  488.      ppIndex = &pIndexTable->pIndex[iCount];/* access index info      */
  489.  
  490.      /*---------------------------------------------------------------*/
  491.      /* open the specified index, complete its information structure: */
  492.      /* invoke internal function OpenIndex                            */
  493.      /*---------------------------------------------------------------*/
  494.      iStatus = OpenIndex (pSession,    /* In  -- session pointer      */
  495.                           ppIndex);    /* In/Out index info. (ptr)    */
  496.  
  497.      if (iStatus != RC_TRUE)           /* check OpenIndex status      */
  498.      {                                 /* index info. is not modified */
  499.       /*--------------------------------------------------------------*/
  500.       /* handle the function error ...                                */
  501.       /*--------------------------------------------------------------*/
  502.       HandleExit (pServerTable,        /* In  -- server table pointer */
  503.                   pArea);              /* In  -- work area pointer    */
  504.       return (iStatus);                /* return to the caller        */
  505.      }                                 /* endif OpenIndex failed      */
  506.  
  507.      memset(work,   0x00, sizeof(work));
  508.      memcpy(work, (PCHAR ) (*ppIndex)->pName->value, 8 );
  509.      printf( " index opened successfully  = %s  \n", work );
  510.  
  511.      /*---------------------------------------------------------------*/
  512.      /* set current index information pointer                         */
  513.      /*---------------------------------------------------------------*/
  514.       pIndex[iCount] = *ppIndex;
  515.    }
  516.    /*-----------------------------------------------------------------*/
  517.    /* create an index group containing the three opened indexes       */
  518.    /*-----------------------------------------------------------------*/
  519.    /*-----------------------------------------------------------------*/
  520.    /* access datastream area and initialize length                    */
  521.    /*-----------------------------------------------------------------*/
  522.     pDataStream  = pArea;              /* initialize target pointer   */
  523.     ulDataLength = SIZEOF_DATA_AREA;   /* initialize remaining length */
  524.  
  525.     for(iCount = 0; iCount < pIndexTable->usIndexCount; iCount++ )
  526.     {
  527.       ppIndex = &pIndexTable->pIndex[iCount];/* access index info     */
  528.  
  529.       *pulIndexHandle = (*ppIndex)->ulHandle; /*save index handle in  */
  530.       pulIndexHandle++;                       /*index group table     */
  531.  
  532.       iStatus = iStatus &
  533.                 WriteDataItem (ID_XNAM, IT_ATOMIC,
  534.                                VAL2(&(*ppIndex)->pName->ll) - 5,
  535. //                               (USHORT )(*ppIndex)->pName->ll - 5,
  536.                                (PCHAR ) (*ppIndex)->pName->value,
  537.                                &ulDataLength, &pDataStream);
  538.  
  539.       memset(work,   0x00, sizeof(work));
  540.       memcpy(work, (PCHAR ) (*ppIndex)->pName->value, 8 );
  541.       printf( " new index in group   = %s  \n", work );
  542.       printf( " index handle         = %lu \n", *pulIndexHandle  );
  543.     }
  544.     if (iStatus != RC_TRUE)            /* check WriteDataItem status  */
  545.     {
  546.  
  547.       /*--------------------------------------------------------------*/
  548.       /* handle the function error ...                                */
  549.       /*--------------------------------------------------------------*/
  550.       HandleExit (pServerTable,        /* In  -- server table pointer */
  551.                   pArea);              /* In  -- work area pointer    */
  552.       return (iStatus);                /* return to the caller        */
  553.     }
  554.    /*-----------------------------------------------------------------*/
  555.    /* set number of entries in index group table                      */
  556.    /*-----------------------------------------------------------------*/
  557.     pGroupTable->usHandleCount = iCount;
  558.  
  559.     ulDataLength = (ULONG )(pDataStream - pArea);
  560.     pDataStream  = pArea;              /* set pointer to datastream   */
  561.  
  562.    /*-----------------------------------------------------------------*/
  563.    /* create an index group using API service EhwCreateIndexGroup     */
  564.    /*-----------------------------------------------------------------*/
  565.    ulReturnCode =
  566.    EhwCreateIndexGroup(pSession,       /* In  -- session pointer      */
  567.               ulDataLength,            /* In  -- datastream length    */
  568.               pDataStream,             /* In  -- index listquery                */
  569.               &ulGroupHandle,          /* Out -- index group handle   */
  570.               &ulDiagnosisInfo);       /* Out -- diagnosis info       */
  571.  
  572.    printf ("ReturnCode (EhwCreateIndexGroup) = %d \n", ulReturnCode);
  573.  
  574.    /*------------------------------------------------------------------+
  575.    |  start of the search processing                                   |
  576.    +------------------------------------------------------------------*/
  577.    ulDataLength = SIZEOF_DATA_AREA;    /* initialize remaining length */
  578.    pDataStream  = pArea;               /* initialize target pointer   */
  579.  
  580.    /*-----------------------------------------------------------------*/
  581.    /* write a query datastream to the work area                       */
  582.    /*-----------------------------------------------------------------*/
  583.  
  584.                                        /* write RANK option item      */
  585.    iStatus = WriteDataItem (ID_RANK, IT_ATOMIC, 0, NULL,
  586.                             &ulDataLength, &pDataStream);
  587.  
  588.                                        /* write CCSID item            */
  589.                                        /* invert the CCSID item value */
  590.                                        /* to big-endian format        */
  591.    usValue = ID(QUERY_CCSID);          /* using macro ID() or VAL2()  */
  592.    iStatus = iStatus &
  593.              WriteDataItem (ID_CCSID, IT_ATOMIC,
  594.                            (USHORT )sizeof(usValue), (PCHAR )&usValue,
  595.                             &ulDataLength, &pDataStream);
  596.  
  597.                                        /* write language id item      */
  598.                                        /* invert the language id item */
  599.                                        /* value to big-endian format  */
  600.    usValue = ID(QUERY_LANG);           /* using macro ID() or VAL2()  */
  601.    iStatus = iStatus &
  602.              WriteDataItem (ID_LANG, IT_ATOMIC,
  603.                            (USHORT )sizeof(usValue), (PCHAR )&usValue,
  604.                             &ulDataLength, &pDataStream);
  605.  
  606.                                        /* write SARG start item       */
  607.    iStatus = iStatus &
  608.              WriteDataItem (ID_SARG, IT_START, 0, NULL,
  609.                             &ulDataLength, &pDataStream);
  610.  
  611.                                        /* write TERM item             */
  612.    iStatus = iStatus &
  613.              WriteDataItem (ID_TERM, IT_ATOMIC,
  614.                             strlen(word1), word1,
  615.                             &ulDataLength, &pDataStream);
  616.  
  617. //                            (USHORT )(sizeof(QUERY_WORD01) - 1),
  618. //                            QUERY_WORD01,
  619.  
  620.                                        /* write SARG end item         */
  621.    iStatus = iStatus &
  622.              WriteDataItem (ID_SARG, IT_END, 0, NULL,
  623.                             &ulDataLength, &pDataStream);
  624.  
  625.                                        /* write AND item              */
  626.    if( strlen(word2) > 0)
  627.    {
  628.  
  629.    iStatus = iStatus &
  630.              WriteDataItem (ID_LOR, IT_ATOMIC, 0, NULL,
  631. //             WriteDataItem (ID_AND, IT_ATOMIC, 0, NULL,      // to AND the terms
  632.                             &ulDataLength, &pDataStream);
  633.  
  634.                                        /* write SARG start item       */
  635.    iStatus = iStatus &
  636.              WriteDataItem (ID_SARG, IT_START, 0, NULL,
  637.                             &ulDataLength, &pDataStream);
  638.  
  639.                                        /* write TERM item             */
  640.    iStatus = iStatus &
  641.              WriteDataItem (ID_TERM, IT_ATOMIC,
  642.                             strlen(word2), word2,
  643.                             &ulDataLength, &pDataStream);
  644.  
  645. //                            (USHORT )(sizeof(QUERY_WORD02) - 1),
  646. //                            QUERY_WORD02,
  647.  
  648.                                        /* write SARG end item         */
  649.    iStatus = iStatus &
  650.              WriteDataItem (ID_SARG, IT_END, 0, NULL,
  651.                             &ulDataLength, &pDataStream);
  652.  
  653.  
  654.    }
  655.  
  656.    if (iStatus != RC_TRUE)             /* check if WriteDataItem      */
  657.    {                                   /* status area is too small to */
  658.                                        /* hold the session information*/
  659.       /*--------------------------------------------------------------*/
  660.       /* handle the function error ...                                */
  661.       /*--------------------------------------------------------------*/
  662.       HandleExit (pServerTable,        /* In  -- server table pointer */
  663.                   pArea);              /* In  -- work area pointer    */
  664.       return (iStatus);                /* return to the caller        */
  665.    }
  666.                                        /* set length of query data    */
  667.    ulDataLength = (ULONG )(pDataStream - pArea);
  668.    pDataStream  = pArea;               /* set pointer to datastream   */
  669.  
  670.    /*-----------------------------------------------------------------*/
  671.    /* Start a search using API function EhwSearch                     */
  672.    /*-----------------------------------------------------------------*/
  673.    ulReturnCode =
  674.    EhwSearch (pSession,                /* In  -- session pointer      */
  675.               ulGroupHandle,           /* In  -- index group handle   */
  676.               ulDataLength,            /* In  -- datastream length    */
  677.               pDataStream,             /* In  -- query                */
  678.               &ulResultHandle,         /* Out -- result handle        */
  679.               &ulResultSize,           /* Out -- result size          */
  680.               &ulDiagnosisInfo);       /* Out -- diagnosis info       */
  681.  
  682.    printf ("ReturnCode (EhwSearch)           = %d \n", ulReturnCode);
  683.    printf ("ResultSize (EhwSearch)           = %d \n", ulResultSize);
  684.  
  685.    if ( ulReturnCode != RC_DONE &&      /* check the API return code   */
  686.         ulResultSize > 0 )
  687.  
  688.    {
  689.       switch (ulReturnCode)            /* select the warning codes    */
  690.       {
  691.          case RC_DICTIONARY_NOT_FOUND:
  692.          case RC_STOPWORD_IGNORED:
  693.             /*--------------------------------------------------------*/
  694.             /* handle the warning code ...                            */
  695.             /*--------------------------------------------------------*/
  696.             break;                     /* ignore the warning code     */
  697.  
  698.          case RC_INDEX_SPECIFIC_ERROR:
  699.             /*--------------------------------------------------------*/
  700.             /* get information about index-specific return codes      */
  701.             /* by calling function GetProblemInfo                     */
  702.             /*--------------------------------------------------------*/
  703.  
  704.              iStatus = GetProblemInfo (pSession, ulResultHandle,
  705.                                        &pIndexProblem);
  706.  
  707.              if (iStatus != RC_TRUE)   /* check return code           */
  708.              /*-------------------------------------------------------*/
  709.              /* handle the function error ...                         */
  710.              /*-------------------------------------------------------*/
  711.              {
  712.              HandleExit (pServerTable, /* In  -- server table pointer */
  713.                          pArea);       /* In  -- work area pointer    */
  714.              return (iStatus);         /* return to the caller        */
  715.              }                         /* endif GetProblemInfo failed */
  716.  
  717.             /*--------------------------------------------------------*/
  718.             /* print all error return codes                           */
  719.             /*--------------------------------------------------------*/
  720.              if(pIndexProblem)
  721.              {
  722.                for(iCount=0;
  723.                    (&pIndexProblem->IdxProblem[iCount])->IndexName;
  724.                    iCount++)
  725.                {
  726.                  printf("Index with Problem: %s\n",
  727.                    (&pIndexProblem->IdxProblem[iCount])->IndexName);
  728.                  printf("ReturnCode: %d\n",
  729.                    (&pIndexProblem->IdxProblem[iCount])->usProblemRc);
  730.                }
  731.             /*--------------------------------------------------------*/
  732.             /* deallocate index problem table and related memory      */
  733.             /*--------------------------------------------------------*/
  734.                for(iCount=0;
  735.                    (&pIndexProblem->IdxProblem[iCount])->IndexName;
  736.                    iCount++)
  737.                {
  738.                 if( (&pIndexProblem->IdxProblem[iCount])->IndexName )
  739.                 free((&(pIndexProblem->IdxProblem[iCount]))->IndexName);
  740.                }
  741.                free(pIndexProblem);
  742.                pIndexProblem = NULL;
  743.  
  744.              }                         /* endif ProblemInfo returned  */
  745.             break;
  746.          default:
  747.             /*--------------------------------------------------------*/
  748.             /* handle the function error ...                          */
  749.             /*--------------------------------------------------------*/
  750.             HandleExit (pServerTable,  /* In  -- server table pointer */
  751.                         pArea);        /* In  -- work area pointer    */
  752.             return (RC_FALSE);         /* return to the caller        */
  753.       }
  754.    }                                   /* endif API call failed       */
  755.  
  756.    if (ulResultSize)                   /* check the result size       */
  757.    {
  758.       /*--------------------------------------------------------------*/
  759.       /* call API EhwCreateResultList to get a handle of the          */
  760.       /* result list object                                           */
  761.       /*--------------------------------------------------------------*/
  762.       ulReturnCode =
  763.       EhwCreateResultList(
  764.                   pSession,            /* In  -- session pointer      */
  765.                   ulResultHandle,      /* In  -- result handle of     */
  766.                                        /*        search result        */
  767.                   &ulResultHandle2,    /* Out -- result handle of new */
  768.                                        /*        result list          */
  769.                   &ulResListSize,      /* Out -- size of result list  */
  770.                   &ulDiagnosisInfo);   /* Out -- diagnosis info       */
  771.  
  772.       printf ("ReturnCode (EhwCreateResultList) = %d \n", ulReturnCode);
  773.       if (ulReturnCode != RC_DONE)     /* check the API return code   */
  774.       {
  775.          /*-----------------------------------------------------------*/
  776.          /* handle the function error ...                             */
  777.          /*-----------------------------------------------------------*/
  778.           HandleExit (pServerTable,    /* In  -- server table pointer */
  779.                       pArea);          /* In  -- work area pointer    */
  780.           return (RC_FALSE);           /* return to the caller        */
  781.       }
  782.  
  783.       /*--------------------------------------------------------------*/
  784.       /* call API function EhwRank to rank the result list            */
  785.       /*--------------------------------------------------------------*/
  786.       ulReturnCode =
  787.       EhwRank( pSession,               /* In  -- session pointer      */
  788.                ulResultHandle,         /* In  -- result handle of     */
  789.                                        /*        search result        */
  790.                &ulDiagnosisInfo);      /* Out -- diagnosis info       */
  791.  
  792.       printf ("ReturnCode (EhwRank)             = %d \n", ulReturnCode);
  793.       if (ulReturnCode != RC_DONE)     /* check the API return code   */
  794.       {
  795.          /*-----------------------------------------------------------*/
  796.          /* handle the function error ...                             */
  797.          /*-----------------------------------------------------------*/
  798.           HandleExit (pServerTable,    /* In  -- server table pointer */
  799.                       pArea);          /* In  -- work area pointer    */
  800.           return (RC_FALSE);           /* return to the caller        */
  801.       }
  802.  
  803.       /*--------------------------------------------------------------*/
  804.       /* build the result information for the current result list:    */
  805.       /* call function ListResult                                     */
  806.       /*--------------------------------------------------------------*/
  807.       iStatus =
  808.       ListResult (pSession,            /* In  -- session pointer      */
  809.                   ulResultHandle2,     /* In  -- result list handle   */
  810.                   ulResultSize,        /* In  -- result size          */
  811.                   LT_RESULT_DOCUMENTS, /* In  -- reference limit      */
  812.                   pIndexTable);        /* In/Out index information    */
  813.  
  814.       if (iStatus != RC_TRUE)          /* check OpenIndex status      */
  815.       {                                /* index info. is not modified */
  816.          /*-----------------------------------------------------------*/
  817.          /* handle the function error ...                             */
  818.          /*-----------------------------------------------------------*/
  819.          HandleExit (pServerTable,     /* In  -- server table pointer */
  820.                      pArea);           /* In  -- work area pointer    */
  821.          return (iStatus);             /* return to the caller        */
  822.       }                                /* endif ListResult failed     */
  823.  
  824.       /*--------------------------------------------------------------*/
  825.       /* select result information for the first index of the         */
  826.       /* indexgroup using API function EhwSelectResultList:           */
  827.       /* write datastream to the work area                            */
  828.       /*--------------------------------------------------------------*/
  829.       ulDataLength = SIZEOF_DATA_AREA; /* initialize remaining length */
  830.       pDataStream  = pArea;            /* initialize target pointer   */
  831.  
  832.       pIndexName   = ((PITEM)(pIndexTable->pIndex[0]->pName))->value;
  833.       IndexNameLen = ((PITEM)(pIndexTable->pIndex[0]->pName))->ll;
  834.  
  835.                                        /* write index name item       */
  836.       iStatus = WriteDataItem (ID_XNAM, IT_ATOMIC,
  837.                                (USHORT )IndexNameLen - 5,
  838.                                (PCHAR ) pIndexName,
  839.                                &ulDataLength, &pDataStream);
  840.  
  841.       if (iStatus != RC_TRUE)          /* check WriteDataItem status  */
  842.       {
  843.         /*------------------------------------------------------------*/
  844.         /* handle the function error ...                              */
  845.         /*------------------------------------------------------------*/
  846.          HandleExit (pServerTable,     /* In  -- server table pointer */
  847.                      pArea);           /* In  -- work area pointer    */
  848.          return (iStatus);             /* return to the caller        */
  849.       }
  850.  
  851.       ulDataLength = (ULONG )(pDataStream - pArea);
  852.       pDataStream  = pArea;            /* set pointer to datastream   */
  853.       /*--------------------------------------------------------------*/
  854.       /* call API EhwSelectResultList                                 */
  855.       /*--------------------------------------------------------------*/
  856.       ulReturnCode =
  857.       EhwSelectResultList(pSession,    /* In  -- session pointer      */
  858.                      ulResultHandle2,  /* In  -- result handle from   */
  859.                                        /*        EhwCreateResultList  */
  860.                      ulDataLength,     /* In  -- datastream length    */
  861.                      pDataStream,      /* In  -- datastream           */
  862.                      &ulResultHandle3, /* Out -- result list handle   */
  863.                      &ulResListSize,   /* Out -- size of result list  */
  864.                      &ulDiagnosisInfo);/* Out -- diagnosis info.      */
  865.  
  866.       printf ("ReturnCode (EhwSelectResultList) = %d \n", ulReturnCode);
  867.                                        /* check the API return code   */
  868.       if ( ulReturnCode != RC_DONE )
  869.       {
  870.          /*-----------------------------------------------------------*/
  871.          /* handle the function error ...                             */
  872.          /*-----------------------------------------------------------*/
  873.          HandleExit (pServerTable,     /* In  -- server table pointer */
  874.                      pArea);           /* In  -- work area pointer    */
  875.          return (iStatus);             /* return to the caller        */
  876.       }
  877.  
  878.       /*--------------------------------------------------------------*/
  879.       /* sort result list by rank value in descending order:          */
  880.       /* write datastream to the work area                            */
  881.       /*--------------------------------------------------------------*/
  882.       ulDataLength = SIZEOF_DATA_AREA; /* initialize remaining length */
  883.       pDataStream  = pArea;            /* initialize target pointer   */
  884.  
  885.                                        /* write SSP start item        */
  886.       iStatus = WriteDataItem (ID_SSP, IT_START, 0, NULL,
  887.                                &ulDataLength, &pDataStream);
  888.  
  889.                                        /* write attribute item        */
  890.       attribute = SFID_RVAL;
  891.       iStatus = iStatus &
  892.                 WriteDataItem (ID_SFID, IT_ATOMIC,
  893.                                (USHORT )sizeof(UCHAR),
  894.                                (PCHAR ) &attribute,
  895.                                &ulDataLength, &pDataStream);
  896.  
  897.                                        /* write sort order item      */
  898.       iStatus = iStatus &
  899.                 WriteDataItem (ID_SOD, IT_ATOMIC, 0, NULL,
  900.                                &ulDataLength, &pDataStream);
  901.  
  902.                                        /* write SSP end item         */
  903.       iStatus = WriteDataItem (ID_SSP, IT_END, 0, NULL,
  904.                                &ulDataLength, &pDataStream);
  905.  
  906.       if (iStatus != RC_TRUE)          /* check WriteDataItem status  */
  907.       {
  908.         /*------------------------------------------------------------*/
  909.         /* handle the function error ...                              */
  910.         /*------------------------------------------------------------*/
  911.       }
  912.  
  913.       ulDataLength = (ULONG )(pDataStream - pArea);
  914.       pDataStream  = pArea;            /* set pointer to datastream   */
  915.       /*--------------------------------------------------------------*/
  916.       /* call API EhwSort                                             */
  917.       /*--------------------------------------------------------------*/
  918.       ulReturnCode =
  919.       EhwSort (pSession,               /* In  -- session pointer      */
  920.                ulResultHandle3,        /* In  -- result handle        */
  921.                ulDataLength,           /* In  -- datastream length    */
  922.                pDataStream,            /* In  -- datastream           */
  923.                &ulDiagnosisInfo);      /* Out -- diagnosis info.      */
  924.  
  925.       printf ("ReturnCode (EhwSort)             = %d \n", ulReturnCode);
  926.                                        /* check the API return code   */
  927.       if ( ulReturnCode != RC_DONE )
  928.       {
  929.          /*-----------------------------------------------------------*/
  930.          /* handle the function error ...                             */
  931.          /*-----------------------------------------------------------*/
  932.          HandleExit (pServerTable,     /* In  -- server table pointer */
  933.                      pArea);           /* In  -- work area pointer    */
  934.          return (RC_FALSE);            /* return to the caller        */
  935.       }
  936.  
  937.       /*--------------------------------------------------------------*/
  938.       /* call function ListResult to get the sorted result list       */
  939.       /*--------------------------------------------------------------*/
  940.       iStatus =
  941.       ListResult (pSession,            /* In  -- session pointer      */
  942.                   ulResultHandle3,     /* In  -- result handle        */
  943.                   ulResListSize,       /* In  -- size of result list  */
  944.                   LT_RESULT_DOCUMENTS, /* In  -- reference limit      */
  945.                   pIndexTable);        /* In/Out index information    */
  946.  
  947.       if (iStatus != RC_TRUE)          /* check OpenIndex status      */
  948.       {                                /* index info. is not modified */
  949.          /*-----------------------------------------------------------*/
  950.          /* handle the function error ...                             */
  951.          /*-----------------------------------------------------------*/
  952.          HandleExit (pServerTable,     /* In  -- server table pointer */
  953.                      pArea);           /* In  -- work area pointer    */
  954.          return (iStatus);             /* return to the caller        */
  955.       }                                /* endif ListResult failed     */
  956.  
  957.       /*--------------------------------------------------------------*/
  958.       /* delete all result lists and the search result                */
  959.       /*--------------------------------------------------------------*/
  960.       iStatus =
  961.       DeleteResults  (pSession,        /* In  -- session pointer      */
  962.                       ulResultHandle,  /* In  -- search result handle */
  963.                       pIndexTable      /* In  -- ptr index group table*/
  964.                       );
  965.  
  966.       if (iStatus != RC_DONE)          /* check the function status   */
  967.       {
  968.          /*-----------------------------------------------------------*/
  969.          /* handle the function error ...                             */
  970.          /*-----------------------------------------------------------*/
  971.          HandleExit (pServerTable,     /* In  -- server table pointer */
  972.                      pArea);           /* In  -- work area pointer    */
  973.          return (iStatus);             /* return to the caller        */
  974.       }
  975.    }                                   /* endif result size not zero  */
  976.    /*------------------------------------------------------------------+
  977.    |   end of the search processing                                    |
  978.    +------------------------------------------------------------------*/
  979.  
  980.    /*-----------------------------------------------------------------*/
  981.    /* delete the index group before closing all open indexes          */
  982.    /*-----------------------------------------------------------------*/
  983.    ulReturnCode =
  984.    EhwDeleteIndexGroup (pSession,      /* In  -- session pointer      */
  985.                         ulGroupHandle, /* In  -- index handle         */
  986.                      &ulDiagnosisInfo);/* Out -- diagnosis info.      */
  987.  
  988.    printf ("ReturnCode (EhwDeleteIndexGroup) = %d \n", ulReturnCode);
  989.    /*-----------------------------------------------------------------*/
  990.    /* close all currently open information retrieval indexes          */
  991.    /*-----------------------------------------------------------------*/
  992.    for(iCount = 0; pGroupTable->usHandleCount > 0;
  993.               pGroupTable->usHandleCount--, iCount++)
  994.    {
  995.                                               /* access index handle  */
  996.      ulIndexHandle = pGroupTable->ulHandle[iCount];
  997.  
  998.      ulReturnCode =
  999.      EhwCloseIndex (pSession,          /* In  -- session pointer      */
  1000.                     ulIndexHandle,     /* In  -- index handle         */
  1001.                     &ulDiagnosisInfo); /* Out -- diagnosis info.      */
  1002.  
  1003.      printf ("ReturnCode (EhwCloseIndex)       = %d \n", ulReturnCode);
  1004.  
  1005.      if (ulReturnCode != RC_DONE)      /* check the API return code   */
  1006.      {
  1007.       /*--------------------------------------------------------------*/
  1008.       /* handle the function error ...                                */
  1009.       /*--------------------------------------------------------------*/
  1010.       iStatus = RC_FALSE;              /* set function status code    */
  1011.      }                                 /* endif API call failed       */
  1012.    }                                   /* endfor all open indexes     */
  1013.    /*-----------------------------------------------------------------*/
  1014.    /* terminate search session by calling function HandleExit         */
  1015.    /*-----------------------------------------------------------------*/
  1016.    HandleExit (pServerTable,           /* In  -- server table pointer */
  1017.                pArea);                 /* In  -- work area pointer    */
  1018.  
  1019.  
  1020.    printf ("StatusCode (IMLSMP02)           = %d \n", iStatus);
  1021.    return (iStatus);                   /* return to the caller        */
  1022.  
  1023. }                                      /* end of main function        */
  1024.  
  1025. /*=====================================================================+
  1026. |                                                                      |
  1027. | Entry point:  ListServers                                            |
  1028. |                                                                      |
  1029. | Function:     Builds a server table containing the server            |
  1030. |               information for any Text Search  server               |
  1031. |               that can be connected to this application.             |
  1032. |                                                                      |
  1033. | Input                                                                |
  1034. | parameters:   None                                                   |
  1035. |                                                                      |
  1036. | Output                                                               |
  1037. | parameters:   Pointer to server table                                |
  1038. |                                                                      |
  1039. | Return codes: Status ok         RC_TRUE                              |
  1040. |               Status not ok     RC_FALSE                             |
  1041. |                                                                      |
  1042. | Input files:  None                                                   |
  1043. |                                                                      |
  1044. | Output files: None                                                   |
  1045. |                                                                      |
  1046. | Calls:        API functions:                                         |
  1047. |                                                                      |
  1048. |                   EhwListServers                                     |
  1049. |                                                                      |
  1050. | Exits:        Returns to caller                                      |
  1051. |                                                                      |
  1052. |----------------------------------------------------------------------|
  1053. |                                                                      |
  1054. | Program logic:                                                       |
  1055. |                                                                      |
  1056. | - Issue an EhwListServers function call to obtain the server list    |
  1057. |   data stream.                                                       |
  1058. | - Check the API function return code.                                |
  1059. |                                                                      |
  1060. | - Determine the total size of the server list:                       |
  1061. |   Length of server list data stream plus size of server list header. |
  1062. | - Allocate the server table area in this size.                       |
  1063. | - Initialize the server table header fields:                         |
  1064. |   Header text, length of table and number of server entries.         |
  1065. |                                                                      |
  1066. | - Parse the server list data stream:                                 |
  1067. |   While current data pointer has not yet reached the end of data     |
  1068. |                                                                      |
  1069. |    - Select the item identifier                                      |
  1070. |                                                                      |
  1071. |       - When ID_IRS  (server list delimiter)                         |
  1072. |                                                                      |
  1073. |          - If it is an end item (item type = IT_END)                 |
  1074. |                                                                      |
  1075. |             - Increase the server count.                             |
  1076. |             - Skip the current server entry.                         |
  1077. |                                                                      |
  1078. |            Else (item is of type IT_START)                           |
  1079. |                                                                      |
  1080. |             - Initialize the session pointer.                        |
  1081. |             - Initialize the index table pointer.                    |
  1082. |                                                                      |
  1083. |            Endif                                                     |
  1084. |                                                                      |
  1085. |       - When ID_IRSN (server name item)                              |
  1086. |                                                                      |
  1087. |          - Set the server name length and                            |
  1088. |            the server name of current server information structure.  |
  1089. |                                                                      |
  1090. |       - When ID_IRSL (server location item)                          |
  1091. |                                                                      |
  1092. |          - Set the server location.                                  |
  1093. |                                                                      |
  1094. |       - Otherwise -                                                  |
  1095. |                                                                      |
  1096. |      Endselect                                                       |
  1097. |                                                                      |
  1098. |    - Update the data pointer (skip current item).                    |
  1099. |                                                                      |
  1100. |   Endwhile                                                           |
  1101. |                                                                      |
  1102. | - Assign the address of the server list  to the output parameter.    |
  1103. | - Return to the caller.                                              |
  1104. |                                                                      |
  1105. +=====================================================================*/
  1106. /*====================================================================*/
  1107. /*  internal function ListServers (build the Server List)             */
  1108. /*====================================================================*/
  1109. INT    ListServers                     /* hold the servers in a table */
  1110.        (
  1111.         SRVTBL  **ppServerTable        /* Out -- server table pointer */
  1112.        )                               /* function value: status code */
  1113. {                                      /* function variables:         */
  1114.    ULONG     ulReturnCode    = RC_DONE;/* API return code             */
  1115.    ULONG     ulDiagnosisInfo = 0L;     /* API diagnosis information   */
  1116.    ULONG     ulDataLength    = 0L;     /* API datastream length       */
  1117.    PCHAR     pDataStream     = NULL;   /* API datastream pointer      */
  1118.    PCHAR     pDataEnd        = NULL;   /* end of datastream pointer   */
  1119.    PSERVER   pServer         = NULL;   /* server table entry pointer  */
  1120.    PSRVTBL   pServerTable    = NULL;   /* server table pointer        */
  1121.    ULONG     ulTableLength   = 0L;     /* length of server table      */
  1122.  
  1123.  /*-------------------------------------------------------------------*/
  1124.  /*  initialize the output parameter (pointer to server table)        */
  1125.  /*-------------------------------------------------------------------*/
  1126.    *ppServerTable = NULL;
  1127.  
  1128.  /*-------------------------------------------------------------------*/
  1129.  /*  call API service EhwListServers                                  */
  1130.  /*-------------------------------------------------------------------*/
  1131.    ulReturnCode =
  1132.    EhwListServers (&ulDataLength,      /* Out -- datastream length    */
  1133.                    &pDataStream,       /* Out -- server list          */
  1134.                    &ulDiagnosisInfo);  /* Out -- diagnosis info.      */
  1135.  
  1136.    printf ("ReturnCode (EhwListServers)      = %d \n", ulReturnCode);
  1137.  
  1138.    if (ulReturnCode != RC_DONE)        /* check the API return code   */
  1139.    {
  1140.       /*--------------------------------------------------------------*/
  1141.       /* handle the API error ...                                     */
  1142.       /*--------------------------------------------------------------*/
  1143.       return (RC_FALSE);               /* return to the caller        */
  1144.    }                                   /* endif API call failed       */
  1145.  
  1146.    /*-----------------------------------------------------------------*/
  1147.    /* allocate / initialize the server list                           */
  1148.    /*-----------------------------------------------------------------*/
  1149.    /* The size of the server table can be reduced if you first parse  */
  1150.    /* the datastream to determine the number of servers. Then the     */
  1151.    /* actual size to be allocated can be calculated.                  */
  1152.    /*-----------------------------------------------------------------*/
  1153.                                        /* set the server table length */
  1154.    ulTableLength = ulDataLength + offsetof(SRVTBL, Server[0]);
  1155.    pServerTable  = (PSRVTBL )malloc((size_t )ulTableLength);
  1156.    if (!pServerTable)                  /* check if allocation failed  */
  1157.    {
  1158.       /*--------------------------------------------------------------*/
  1159.       /* handle the allocation error ...                              */
  1160.       /*--------------------------------------------------------------*/
  1161.       return (RC_FALSE);               /* return to the caller        */
  1162.    }                                   /* endif allocation failed     */
  1163.                                        /* write the header text       */
  1164.    memcpy(pServerTable->Header,
  1165.           "SrvTable", sizeof(pServerTable->Header));
  1166.                                        /* set the server table length */
  1167.    pServerTable->ulTableLength = ulTableLength;
  1168.    pServerTable->usServerCount = 0;    /* init. the number of entries */
  1169.                                        /* set the table entry pointer */
  1170.    pServer = pServerTable->Server;     /* to the first server entry   */
  1171.  
  1172.    /*-----------------------------------------------------------------*/
  1173.    /* parse the server list datastream, write the table entries       */
  1174.    /*-----------------------------------------------------------------*/
  1175.                                        /* set the ptr to end of data  */
  1176.    pDataEnd = pDataStream + ulDataLength;
  1177.                                        /*check that eod is not reached*/
  1178.    while (pDataStream < pDataEnd)
  1179.    {                                   /* check the item identifier   */
  1180.       switch (((PITEM )pDataStream)->id)
  1181.       {                                /* invert big-endian format    */
  1182.                                        /* using macro ID()            */
  1183.          case ID(ID_IRS):              /* server list delimiter:      */
  1184.                                        /* check if it is an end item  */
  1185.             if (((PITEM )pDataStream)->it == IT_END)
  1186.             {
  1187.                /*-----------------------------------------------------*/
  1188.                /* increase number of servers, skip server table entry */
  1189.                /*-----------------------------------------------------*/
  1190.                pServerTable->usServerCount++;
  1191.                pServer = (PSERVER )
  1192.                          ((PCHAR )pServer + (offsetof(SERV, Name)
  1193.                                              + pServer->usNameLength));
  1194.             }
  1195.             else                       /* server list start item:     */
  1196.             {
  1197.                /*-----------------------------------------------------*/
  1198.                /* initialize current server information               */
  1199.                /*-----------------------------------------------------*/
  1200.                pServer->pSession    = NULL;
  1201.                pServer->pIndexTable = NULL;
  1202.                pServer->pGroupTable = NULL;
  1203.             }
  1204.             break;
  1205.  
  1206.          case ID(ID_IRSN):             /* server name item:           */
  1207.  
  1208.             /*--------------------------------------------------------*/
  1209.             /* set server fields: name length and name                */
  1210.             /*--------------------------------------------------------*/
  1211.             /* overcome big-endian format using macro VAL2()          */
  1212.             /*--------------------------------------------------------*/
  1213.             pServer->usNameLength = VAL2(&(((PITEM )pDataStream)->ll))
  1214.                                     - offsetof(ITEM, value[0]);
  1215.                                        /* copy name to server table   */
  1216.             memcpy(pServer->Name,
  1217.                    ((PITEM )pDataStream)->value,
  1218.                    (size_t )pServer->usNameLength);
  1219.             break;
  1220.  
  1221.          case ID(ID_IRSL):             /* server location item:       */
  1222.  
  1223.             /*--------------------------------------------------------*/
  1224.             /* hold the server location in the server table           */
  1225.             /*--------------------------------------------------------*/
  1226.             pServer->Location = (UCHAR )*((PITEM )pDataStream)->value;
  1227.             break;
  1228.  
  1229.          default:
  1230.                                        /* skip all unknown data items */
  1231.             break;
  1232.       }                                /* endswitch item identifier   */
  1233.                                        /* skip current data item      */
  1234.       /*--------------------------------------------------------------*/
  1235.       /* invert big-endian format using macro VAL2()                  */
  1236.       /*--------------------------------------------------------------*/
  1237.       pDataStream += VAL2(&(((PITEM )pDataStream)->ll));
  1238.    }                                   /* endwhile not end of data    */
  1239.  
  1240.    /*-----------------------------------------------------------------*/
  1241.    /* set output parameter (pointer to server table)                  */
  1242.    /*-----------------------------------------------------------------*/
  1243.    *ppServerTable = pServerTable;
  1244.  
  1245.    return (RC_TRUE);                   /* return to the caller        */
  1246. }                                      /* end of ListServers          */
  1247.  
  1248. /*=====================================================================+
  1249. |                                                                      |
  1250. | Entry point:  ListIndexes                                            |
  1251. |                                                                      |
  1252. | Function:     Builds an index table containing                       |
  1253. |               at most LT_NUMBER_OF_INDEXES                           |
  1254. |               accessible information-retrieval indexes.              |
  1255. |               Creates and initializes the index information          |
  1256. |               for any index.                                         |
  1257. |                                                                      |
  1258. | Input                                                                |
  1259. | parameters:   Session pointer                                        |
  1260. |                                                                      |
  1261. | Output                                                               |
  1262. | parameters:   Pointer to index table                                 |
  1263. |                                                                      |
  1264. | Return codes: Status ok         RC_TRUE                              |
  1265. |               Status not ok     RC_FALSE                             |
  1266. |                                                                      |
  1267. | Input files:  None                                                   |
  1268. |                                                                      |
  1269. | Output files: None                                                   |
  1270. |                                                                      |
  1271. | Calls:        API functions:                                         |
  1272. |                                                                      |
  1273. |                   EhwListIndexes                                     |
  1274. |                                                                      |
  1275. | Exits:        Returns to caller                                      |
  1276. |                                                                      |
  1277. |----------------------------------------------------------------------|
  1278. |                                                                      |
  1279. | Program logic:                                                       |
  1280. |                                                                      |
  1281. | - Determine the total size of the index table:                       |
  1282. |   Size of index table header plus LT_NUMBER_OF_INDEXES times         |
  1283. |   the size of an index table pointer.                                |
  1284. | - Allocate the index table area.                                     |
  1285. | - Initialize the index table header fields:                          |
  1286. |   Header text, length of table, number of index table slots and      |
  1287. |   number of index entries.                                           |
  1288. |                                                                      |
  1289. | - Do until EhwListIndexes has returned the last data block           |
  1290. |            or there are no more slots available in the index table.  |
  1291. |                                                                      |
  1292. |    - Issue an EhwListIndexes function call to obtain an index list   |
  1293. |      datastream block.                                               |
  1294. |    - If the API function indicates an error                          |
  1295. |      - Release all storage allocated until now by this function.     |
  1296. |      - Return to the caller.                                         |
  1297. |      Endif                                                           |
  1298. |                                                                      |
  1299. |    - Parse the index list datastream block:                          |
  1300. |      While the end of current data block is not reached              |
  1301. |                                                                      |
  1302. |       - Check the current item identifier:                           |
  1303. |         If it is an index name item (ID_XNAM)                        |
  1304. |                                                                      |
  1305. |          - Create and initialize the index information:              |
  1306. |             - Calculate the size of index information.               |
  1307. |               (Reserve LT_SIZEOF_LSCE_ITEM bytes for the             |
  1308. |                library services DLL name datastream item).           |
  1309. |             - Allocate the index information area.                   |
  1310. |               If the allocation failed                               |
  1311. |               - Release all storage allocated until now by           |
  1312. |                 this function.                                       |
  1313. |               - Return to the caller.                                |
  1314. |               Endif                                                  |
  1315. |             - Initialize the index information header fields.        |
  1316. |             - Assign the current item length to structure field      |
  1317. |               'length of detail datastream'.                         |
  1318. |             - Copy the current index name item to the                |
  1319. |               index information area.                                |
  1320. |             - Set the index name item pointer.                       |
  1321. |                                                                      |
  1322. |          - Update index table fields:                                |
  1323. |             - Increase the index count in the index table.           |
  1324. |             - Save the current index information pointer.            |
  1325. |                                                                      |
  1326. |          - If all slots of the index table are used                  |
  1327. |             - Leave the while loop.                                  |
  1328. |            Endif                                                     |
  1329. |                                                                      |
  1330. |         Endif                                                        |
  1331. |                                                                      |
  1332. |       - Skip current item (update the data pointer).                 |
  1333. |                                                                      |
  1334. |      Endwhile                                                        |
  1335. |                                                                      |
  1336. |   Enddo                                                              |
  1337. |                                                                      |
  1338. | - Assign the index table address to the output parameter.            |
  1339. | - Return to the caller.                                              |
  1340. |                                                                      |
  1341. +=====================================================================*/
  1342. /*====================================================================*/
  1343. /* internal function ListIndexes (build an index table)               */
  1344. /*====================================================================*/
  1345. INT    ListIndexes                     /* hold the indexes in a table */
  1346.        (
  1347.         PVOID     pSession,            /* In  -- session pointer      */
  1348.         XTBL    **ppIndexTable         /* Out -- index table pointer  */
  1349.        )                               /* function value: status code */
  1350. {                                      /* function variables:         */
  1351.    ULONG     ulReturnCode    = RC_DONE;/* API return code             */
  1352.    ULONG     ulDiagnosisInfo = 0L;     /* API diagnosis information   */
  1353.    ULONG     ulDataLength    = 0L;     /* API datastream length       */
  1354.    PCHAR     pDataStream     = NULL;   /* API datastream pointer      */
  1355.    PCHAR     pDataEnd        = NULL;   /* end of datastream pointer   */
  1356.    PXTBL     pIndexTable     = NULL;   /* pointer to index table      */
  1357.    PINDEX   *ppIndex         = NULL;   /* ptr to index info. pointer  */
  1358.    USHORT    usItemLength    = 0;      /* datastream item length      */
  1359.  
  1360.    /*-----------------------------------------------------------------*/
  1361.    /* initialize the output parameter (pointer to index table)        */
  1362.    /*-----------------------------------------------------------------*/
  1363.    *ppIndexTable = NULL;
  1364.  
  1365.    /*-----------------------------------------------------------------*/
  1366.    /* create an index table for at most LT_NUMBER_OF_INDEXES entries  */
  1367.    /* (LT_NUMBER_OF_INDEXES must be greater than zero !!!)            */
  1368.    /*-----------------------------------------------------------------*/
  1369.    ulDataLength = (offsetof(XTBL, pIndex[0]) +
  1370.                    LT_NUMBER_OF_INDEXES * sizeof(struct IndexInfo));
  1371.    pIndexTable = (PXTBL )malloc((size_t )ulDataLength);
  1372.    if (!pIndexTable)                   /* check if allocation failed  */
  1373.    {
  1374.       /*--------------------------------------------------------------*/
  1375.       /* handle the allocation error ...                              */
  1376.       /*--------------------------------------------------------------*/
  1377.       return (RC_FALSE);               /* return to the caller        */
  1378.    }                                   /* endif allocation failed     */
  1379.                                        /* write the header text       */
  1380.    memcpy(pIndexTable->Header,
  1381.           "IndexTbl", sizeof(pIndexTable->Header));
  1382.                                        /* set the index table length  */
  1383.    pIndexTable->ulTableLength = ulDataLength;
  1384.                                        /* init. the number of slots   */
  1385.    pIndexTable->usIndexSlots  = LT_NUMBER_OF_INDEXES;
  1386.    pIndexTable->usIndexCount  = 0;     /* init. the number of entries */
  1387.    pIndexTable->usResultCount = 0;     /* init. result list count     */
  1388.                                        /* set the table entry pointer */
  1389.    ppIndex = pIndexTable->pIndex;      /* to the first index entry    */
  1390.  
  1391.    /*-----------------------------------------------------------------*/
  1392.    /* call API service EhwListIndex until end of data is indicated    */
  1393.    /* or the limit for number of indexes is reached                   */
  1394.    /*-----------------------------------------------------------------*/
  1395.    do
  1396.    {
  1397.       ulReturnCode =
  1398.       EhwListIndexes (pSession,        /* In  -- session pointer      */
  1399.                       &ulDataLength,   /* Out -- datastream length    */
  1400.                       &pDataStream,    /* Out -- index list           */
  1401.                       &ulDiagnosisInfo /* Out -- diagnosis info.      */
  1402.                      );
  1403.       printf ("ReturnCode (EhwListIndexes)      = %d \n", ulReturnCode);
  1404.                                        /* check the API return code   */
  1405.       if ((ulReturnCode != RC_DONE) &&
  1406.           (ulReturnCode != RC_CONTINUATION_MODE_ENTERED))
  1407.       {
  1408.          /*-----------------------------------------------------------*/
  1409.          /* handle the function error ...                             */
  1410.          /*-----------------------------------------------------------*/
  1411.          free(pIndexTable);            /* release the index table     */
  1412.          return (RC_FALSE);            /* return to the caller        */
  1413.       }                                /* endif API call failed       */
  1414.       /*--------------------------------------------------------------*/
  1415.       /* parse the index list datastream, build the table entries     */
  1416.       /*--------------------------------------------------------------*/
  1417.                                        /* set the ptr to end of data  */
  1418.       pDataEnd = pDataStream + ulDataLength;
  1419.  
  1420.       while (pDataStream < pDataEnd)   /*check that eod is not reached*/
  1421.       {                                /* check the item identifier   */
  1422.                                        /* overcome big-endian format  */
  1423.                                        /* using macro ID()            */
  1424.          if (((PITEM )pDataStream)->id == ID(ID_XNAM))
  1425.          {
  1426.                                        /* index name item:            */
  1427.             /*--------------------------------------------------------*/
  1428.             /* allocate storage for index information                 */
  1429.             /*--------------------------------------------------------*/
  1430.             /* overcome big-endian format using macro VAL2()          */
  1431.             /*--------------------------------------------------------*/
  1432.                                        /* calculate needed data size  */
  1433.             usItemLength = VAL2(&(((PITEM )pDataStream)->ll));
  1434.  
  1435.             ulDataLength = (ULONG )(offsetof(INDEX, Data[0]) +
  1436.                                     usItemLength + LT_SIZEOF_LSCE_ITEM);
  1437.  
  1438.                                        /* allocate index info struct. */
  1439.             *ppIndex = (PINDEX )malloc((size_t )ulDataLength);
  1440.  
  1441.             if (!(*ppIndex))           /* check if allocation failed  */
  1442.             {
  1443.                /*-----------------------------------------------------*/
  1444.                /* handle the allocation error ...                     */
  1445.                /*-----------------------------------------------------*/
  1446.                free(pIndexTable);      /* release the index table     */
  1447.                return (RC_FALSE);      /* return to the caller        */
  1448.             }                          /* endif allocation failed     */
  1449.             /*--------------------------------------------------------*/
  1450.             /* set or initialize the index information fields         */
  1451.             /*--------------------------------------------------------*/
  1452.                                        /* write the header text       */
  1453.             memcpy((*ppIndex)->Header,
  1454.                    "IndxInfo", sizeof((*ppIndex)->Header));
  1455.  
  1456.             (*ppIndex)->ulInfoLength = ulDataLength;
  1457.             (*ppIndex)->ulHandle     = 0L;
  1458.             (*ppIndex)->Type         = 0x00;
  1459.             (*ppIndex)->Property     = 0x00;
  1460.             (*ppIndex)->pDLL         = NULL;
  1461.             (*ppIndex)->ulDataLength = (ULONG )usItemLength;
  1462.             (*ppIndex)->pName        = (PITEM )(*ppIndex)->Data;
  1463.                                        /* copy item to index info.    */
  1464.             memcpy((*ppIndex)->pName,
  1465.                    pDataStream, (size_t )usItemLength);
  1466.  
  1467.             /*--------------------------------------------------------*/
  1468.             /* update number of indexes and index info. pointer       */
  1469.             /*--------------------------------------------------------*/
  1470.             pIndexTable->usIndexCount++;
  1471.             ppIndex++;
  1472.  
  1473.             /*--------------------------------------------------------*/
  1474.             /* check if index table is full                           */
  1475.             /*--------------------------------------------------------*/
  1476.             if (!(pIndexTable->usIndexCount
  1477.                   < pIndexTable->usIndexSlots))  break;
  1478.          }                             /* endif index name item       */
  1479.                                        /* skip current data item      */
  1480.          /*-----------------------------------------------------------*/
  1481.          /* invert USHORT item length from 'big-endian' to 'intel'    */
  1482.          /* format using macro VAL2()                                 */
  1483.          /*-----------------------------------------------------------*/
  1484.          pDataStream += VAL2(&(((PITEM )pDataStream)->ll));
  1485.       }                                /* endwhile not end of data    */
  1486.  
  1487.    }  while ((ulReturnCode == RC_CONTINUATION_MODE_ENTERED) &&
  1488.              (pIndexTable->usIndexCount < pIndexTable->usIndexSlots));
  1489.  
  1490.    /*-----------------------------------------------------------------*/
  1491.    /* set output parameter (pointer to index table)                   */
  1492.    /*-----------------------------------------------------------------*/
  1493.    *ppIndexTable = pIndexTable;
  1494.  
  1495.    return (RC_TRUE);                   /* return to the caller        */
  1496. }                                      /* end of ListIndexes          */
  1497.  
  1498. /*=====================================================================+
  1499. |                                                                      |
  1500. | Entry point:  OpenIndex                                              |
  1501. |                                                                      |
  1502. | Function:     Opens an informaion-retrieval index and adds the       |
  1503. |               index detail information to the provided               |
  1504. |               index information.                                     |
  1505. |                                                                      |
  1506. | Input                                                                |
  1507. | parameters:   Session pointer                                        |
  1508. |               Pointer to index table                                 |
  1509. |                                                                      |
  1510. | Output                                                               |
  1511. | parameters:   Pointer to index table (possibly re-allocated)         |
  1512. |                                                                      |
  1513. | Return codes: Status ok         RC_TRUE                              |
  1514. |               Status not ok     RC_FALSE                             |
  1515. |                                                                      |
  1516. | Input files:  None                                                   |
  1517. |                                                                      |
  1518. | Output files: None                                                   |
  1519. |                                                                      |
  1520. | Calls:        API functions:                                         |
  1521. |                                                                      |
  1522. |                   EhwOpenIndex                                       |
  1523. |                   EhwGetIndexInfo                                    |
  1524. |                   EhwCloseIndex (if an error occurs)                 |
  1525. |                                                                      |
  1526. | Exits:        Returns to caller                                      |
  1527. |                                                                      |
  1528. |----------------------------------------------------------------------|
  1529. |                                                                      |
  1530. | Program logic:                                                       |
  1531. |                                                                      |
  1532. | - Access the index name datastream item pointer provided with the    |
  1533. |   input index information.                                           |
  1534. |                                                                      |
  1535. | - Issue an EhwOpenIndex function call to open the information-       |
  1536. |   retrieval index.                                                   |
  1537. | - Check the API function return code.                                |
  1538. | - Save the returned index handle in the index information structure. |
  1539. |                                                                      |
  1540. | - Issue an EhwGetIndexInfo function call to obtain the index         |
  1541. |   detail information datastream.                                     |
  1542. | - If the API function return code indicates an error                 |
  1543. |    - Invoke the API function EhwCloseIndex to close the open index.  |
  1544. |    - Reset the index handle field in the index information.          |
  1545. |    - Set the function status code.                                   |
  1546. |    - Return to the caller.                                           |
  1547. |   Endif                                                              |
  1548. |                                                                      |
  1549. | - Parse the index detail information datastream:                     |
  1550. |   While the end of data is not yet reached                           |
  1551. |                                                                      |
  1552. |    - Select the item identifier                                      |
  1553. |                                                                      |
  1554. |       - When ID_XTYP (index type item)                               |
  1555. |                                                                      |
  1556. |          - Save the index type in the index information structure.   |
  1557. |                                                                      |
  1558. |       - When ID_LSCE (library services DLL name item)                |
  1559. |                                                                      |
  1560. |          - Check if the LSCE item fits into the index information.   |
  1561. |            If not then re-allocate the index information.            |
  1562. |             - If the re-allocation failed                            |
  1563. |                - Invoke the API function EhwCloseIndex.              |
  1564. |                - Reset the current index handle.                     |
  1565. |                - Set the function status code.                       |
  1566. |                - Return to the caller.                               |
  1567. |               Endif                                                  |
  1568. |             - Update information length and name item pointer.       |
  1569. |             - Set the output parameter (index information pointer).  |
  1570. |            Endif                                                     |
  1571. |          - Set the pointer to LSCE (library services DLL name) item. |
  1572. |          - Copy the LSCE item to the index information.              |
  1573. |          - Update the length of index detail datastream.             |
  1574. |                                                                      |
  1575. |       - Otherwise -                                                  |
  1576. |                                                                      |
  1577. |      Endselect                                                       |
  1578. |                                                                      |
  1579. |    - Skip current item (update the data pointer).                    |
  1580. |                                                                      |
  1581. |   Endwhile                                                           |
  1582. |                                                                      |
  1583. | - Return to the caller.                                              |
  1584. |                                                                      |
  1585. +=====================================================================*/
  1586. /*====================================================================*/
  1587. /* internal function OpenIndex (open index, complete the index info.) */
  1588. /*====================================================================*/
  1589. INT    OpenIndex                       /* open the specified index    */
  1590.        (
  1591.         PVOID     pSession,            /* In  -- session pointer      */
  1592.         INDEX   **ppIndex              /* In/Out index info. (ptr)    */
  1593.        )                               /* function value: status code */
  1594. {                                      /* function variables:         */
  1595.    ULONG     ulReturnCode    = RC_DONE;/* API return code             */
  1596.    ULONG     ulDiagnosisInfo = 0L;     /* API diagnosis information   */
  1597.    ULONG     ulIndexHandle   = 0L;     /* API index handle            */
  1598.    ULONG     ulDataLength    = 0L;     /* API datastream length       */
  1599.    PCHAR     pDataStream     = NULL;   /* API datastream pointer      */
  1600.    PCHAR     pDataEnd        = NULL;   /* end of datastream pointer   */
  1601.    USHORT    usItemLength    = 0;      /* datastream item length      */
  1602.                                        /* index information pointer   */
  1603.    PINDEX    pIndex          = *ppIndex;
  1604.  
  1605.    /*-----------------------------------------------------------------*/
  1606.    /* access the index name item in the index information structure   */
  1607.    /*-----------------------------------------------------------------*/
  1608.                                        /* invert the item length from */
  1609.                                        /* big-endian to intel format  */
  1610.    usItemLength = VAL2(&(pIndex->pName->ll));
  1611.  
  1612.    /*-----------------------------------------------------------------*/
  1613.    /* set length and pointer of index information datastream          */
  1614.    /*-----------------------------------------------------------------*/
  1615.    ulDataLength = (ULONG )usItemLength;
  1616.    pDataStream  = (PCHAR )pIndex->pName;
  1617.  
  1618.    /*-----------------------------------------------------------------*/
  1619.    /* call API service to open the information retrieval index        */
  1620.    /*-----------------------------------------------------------------*/
  1621.    ulReturnCode =
  1622.    EhwOpenIndex (pSession,             /* In  -- session pointer      */
  1623.                  ulDataLength,         /* In  -- datastream length    */
  1624.                  pDataStream,          /* In  -- index list           */
  1625.                  &ulIndexHandle,       /* Out -- index handle         */
  1626.                  &ulDiagnosisInfo);    /* Out -- diagnosis info.      */
  1627.  
  1628.    printf ("ReturnCode (EhwOpenIndex)        = %d \n", ulReturnCode);
  1629.  
  1630.    if (ulReturnCode == RC_INDEX_SUSPENDED)
  1631.    {
  1632.       /*--------------------------------------------------------------*/
  1633.       /* issue a message to inform the application that the index     */
  1634.       /* is suspended at the moment                                   */
  1635.       /*--------------------------------------------------------------*/
  1636.       return (RC_TRUE);                /* return to the caller        */
  1637.  
  1638.    }
  1639.  
  1640.    if (ulReturnCode != RC_DONE)
  1641.    {
  1642.       /*--------------------------------------------------------------*/
  1643.       /* handle the function error ...                                */
  1644.       /*--------------------------------------------------------------*/
  1645.       return (RC_FALSE);               /* return to the caller        */
  1646.    }                                   /* endif API call failed       */
  1647.    pIndex->ulHandle = ulIndexHandle;   /* save the index handle       */
  1648.  
  1649.    /*-----------------------------------------------------------------*/
  1650.    /* invoke API service to get the index detail information          */
  1651.    /*-----------------------------------------------------------------*/
  1652.    ulReturnCode =
  1653.    EhwGetIndexInfo (pSession,          /* In  -- session pointer      */
  1654.                     ulIndexHandle,     /* In  -- index handle         */
  1655.                     &ulDataLength,     /* Out -- datastream length    */
  1656.                     &pDataStream,      /* Out -- index list           */
  1657.                     &ulDiagnosisInfo); /* Out -- diagnosis info.      */
  1658.  
  1659.    printf ("ReturnCode (EhwGetIndexInfo)     = %d \n", ulReturnCode);
  1660.  
  1661.    if (ulReturnCode != RC_DONE)        /* check the API return code   */
  1662.    {
  1663.       /*--------------------------------------------------------------*/
  1664.       /* handle the function error ...                                */
  1665.       /*--------------------------------------------------------------*/
  1666.       ulReturnCode =                   /* close current index         */
  1667.       EhwCloseIndex (pSession,         /* In  -- session pointer      */
  1668.                      ulIndexHandle,    /* In  -- index handle         */
  1669.                      &ulDiagnosisInfo);/* Out -- diagnosis info.      */
  1670.  
  1671.       printf ("ReturnCode (EhwCloseIndex)     = %d \n", ulReturnCode);
  1672.  
  1673.       pIndex->ulHandle = 0L;           /* reset the index handle      */
  1674.       return (RC_FALSE);               /* return to the caller        */
  1675.    }                                   /* endif API call failed       */
  1676.  
  1677.    /*-----------------------------------------------------------------*/
  1678.    /* parse the index information datastream                          */
  1679.    /*-----------------------------------------------------------------*/
  1680.                                        /* set the ptr to end of data  */
  1681.    pDataEnd = pDataStream + ulDataLength;
  1682.                                        /* check if eod is not reached */
  1683.    while (pDataStream < pDataEnd)
  1684.    {                                   /* check the item identifier   */
  1685.       switch (((PITEM )pDataStream)->id)
  1686.       {                                /* overcome big-endian format  */
  1687.                                        /* using macro ID()            */
  1688.          case ID(ID_XTYP):             /* index type item:            */
  1689.  
  1690.             /*--------------------------------------------------------*/
  1691.             /* save index type in the index information structure     */
  1692.             /*--------------------------------------------------------*/
  1693.             pIndex->Type = (UCHAR )*((PITEM )pDataStream)->value;
  1694.             break;
  1695.  
  1696.          case ID(ID_LSCE):             /* LS client DLL item:         */
  1697.  
  1698.             /*--------------------------------------------------------*/
  1699.             /* check if the DLL item fits into index information      */
  1700.             /*--------------------------------------------------------*/
  1701.             /* invert 'big-endian' item length using macro VAL2()     */
  1702.             /*--------------------------------------------------------*/
  1703.             usItemLength = VAL2(&(((PITEM )pDataStream)->ll));
  1704.                                        /* determine needed info. size */
  1705.             ulDataLength = (offsetof(INDEX, Data[0]) +
  1706.                             pIndex->ulDataLength     +
  1707.                             (ULONG )usItemLength);
  1708.  
  1709.             if (ulDataLength > pIndex->ulInfoLength)
  1710.             {
  1711.                /*-----------------------------------------------------*/
  1712.                /* extend (re-allocate) the index information          */
  1713.                /*-----------------------------------------------------*/
  1714.                pIndex = (PINDEX )realloc(pIndex, (size_t )ulDataLength);
  1715.  
  1716.                if (!pIndex)            /* check if allocation failed  */
  1717.                {
  1718.                   /*--------------------------------------------------*/
  1719.                   /* handle the allocation error ...                  */
  1720.                   /*--------------------------------------------------*/
  1721.                   ulReturnCode =       /* close current index         */
  1722.                   EhwCloseIndex
  1723.                   (pSession,           /* In  -- session pointer      */
  1724.                    ulIndexHandle,      /* In  -- index handle         */
  1725.                    &ulDiagnosisInfo);  /* Out -- diagnosis info.      */
  1726.  
  1727.                   printf ("ReturnCode (EhwCloseIndex)     = %d \n",
  1728.                           ulReturnCode);
  1729.  
  1730.                                        /* reset the index handle      */
  1731.                   pIndex->ulHandle = 0L;
  1732.                   return (RC_FALSE);   /* return to the caller        */
  1733.                }                       /* endif allocation failed     */
  1734.  
  1735.                /*-----------------------------------------------------*/
  1736.                /* update information length and name item pointer     */
  1737.                /*-----------------------------------------------------*/
  1738.                pIndex->ulInfoLength = ulDataLength;
  1739.                pIndex->pName        = (PITEM )pIndex->Data;
  1740.  
  1741.                /*-----------------------------------------------------*/
  1742.                /* set output parameter (pointer to index information) */
  1743.                /*-----------------------------------------------------*/
  1744.                *ppIndex = pIndex;
  1745.             }
  1746.             /*--------------------------------------------------------*/
  1747.             /* copy LS DLL item to index information                  */
  1748.             /*--------------------------------------------------------*/
  1749.             pIndex->pDLL = (PITEM )
  1750.                            (pIndex->Data + pIndex->ulDataLength);
  1751.  
  1752.             memcpy(pIndex->pDLL,
  1753.                    pDataStream, (size_t )usItemLength);
  1754.                                        /* set index datastream length */
  1755.             pIndex->ulDataLength += (ULONG )usItemLength;
  1756.             break;
  1757.  
  1758.          default:
  1759.  
  1760.             break;
  1761.       }                                /* endswitch item identifier   */
  1762.                                        /* skip current data item      */
  1763.       /*--------------------------------------------------------------*/
  1764.       /* invert USHORT item length from 'big-endian' to 'intel'       */
  1765.       /* format using macro VAL2()                                    */
  1766.       /*--------------------------------------------------------------*/
  1767.       pDataStream += VAL2(&(((PITEM )pDataStream)->ll));
  1768.  
  1769.    }                                   /* endwhile not end of data    */
  1770.    return (RC_TRUE);
  1771. }                                      /* end of OpenIndex()          */
  1772.  
  1773. /*=====================================================================+
  1774. |                                                                      |
  1775. | Entry point:  ListResult                                             |
  1776. |                                                                      |
  1777. | Function:     Builds result information containing the search        |
  1778. |               result datastream and a specified number of            |
  1779. |               document item reference pointers.                      |
  1780. |               (The number of references is limited by the            |
  1781. |                reference limit and the result size parameters.)      |
  1782. |                                                                      |
  1783. | Input                                                                |
  1784. | parameters:   Session pointer                                        |
  1785. |               Result handle                                          |
  1786. |               Result size                                            |
  1787. |               Reference limit (maximum number of documents to be     |
  1788. |                                referenced in the result information) |
  1789. |               Index information                                      |
  1790. |                                                                      |
  1791. | Output                                                               |
  1792. | parameters:   Index information                                      |
  1793. |                                                                      |
  1794. | Return codes: Status ok         RC_TRUE                              |
  1795. |               Status not ok     RC_FALSE                             |
  1796. |                                                                      |
  1797. | Input files:  None                                                   |
  1798. |                                                                      |
  1799. | Output files: None                                                   |
  1800. |                                                                      |
  1801. | Calls:        API functions:                                         |
  1802. |                                                                      |
  1803. |                   EhwGetResultList                                   |
  1804. |                                                                      |
  1805. | Exits:        Returns to caller                                      |
  1806. |                                                                      |
  1807. |----------------------------------------------------------------------|
  1808. |                                                                      |
  1809. | Program logic:                                                       |
  1810. |                                                                      |
  1811. | - Determine the number of document pointers using the                |
  1812. |   reference limit and result size parameters and calculate           |
  1813. |   the size of the result information.                                |
  1814. | - Allocate the result information area.                              |
  1815. | - Initialize the result information area fields.                     |
  1816. | - Define a work data list structure temporarily used to              |
  1817. |   anchor the first result list information block.                    |
  1818. |                                                                      |
  1819. | - Do until EhwGetResultList has returned the last data block.        |
  1820. |                                                                      |
  1821. |    - Issue an EhwGetResultList function call to obtain a result      |
  1822. |      list datastream block.                                          |
  1823. |    - If the API function indicates an error                          |
  1824. |       - If at least one data list area is allocated                  |
  1825. |          - Save the first data list area in the result information.  |
  1826. |          - Set the function status code.                             |
  1827. |          - Return to the caller.                                     |
  1828. |         Endif                                                        |
  1829. |      Endif                                                           |
  1830. |                                                                      |
  1831. |    - Allocate a 'new' data list area for the returned data block     |
  1832. |      and anchor it in the 'old' data list area (next data pointer).  |
  1833. |      If the allocation failed                                        |
  1834. |       - Save the first data list area in the result information.     |
  1835. |       - Set the function status code.                                |
  1836. |       - Return to the caller.                                        |
  1837. |      Endif                                                           |
  1838. |                                                                      |
  1839. |    - Initialize the data list fields (next data pointer).            |
  1840. |    - Save length and data block in the current data list area.       |
  1841. |                                                                      |
  1842. |    - Update the result data length field in the result information.  |
  1843. |                                                                      |
  1844. |   Enddo                                                              |
  1845. |                                                                      |
  1846. | - Anchor the first data list area in the result information.         |
  1847. | - Save the result information pointer in the index information.      |
  1848. |                                                                      |
  1849. | - Set the document reference pointers in the result information:     |
  1850. |   (Parse the result list datastream starting with the first          |
  1851. |    anchored data list area.)                                         |
  1852. |   While the current data list is not the last one                    |
  1853. |                                                                      |
  1854. |      While the end of current data block is not reached              |
  1855. |                                                                      |
  1856. |       - Check the current item identifier:                           |
  1857. |         If it is a document identifier item (ID_DID)                 |
  1858. |                                                                      |
  1859. |          - Assign the current item pointer to the current            |
  1860. |            document reference pointer.                               |
  1861. |          - Increase the reference counter in the result information. |
  1862. |                                                                      |
  1863. |          - if the document reference limit is reached                |
  1864. |             - Set the function status code.                          |
  1865. |             - Return to the caller.                                  |
  1866. |            Endif                                                     |
  1867. |                                                                      |
  1868. |          - Update the current document reference pointer.            |
  1869. |                                                                      |
  1870. |         Endif                                                        |
  1871. |                                                                      |
  1872. |       - Skip current item (update the data pointer).                 |
  1873. |                                                                      |
  1874. |      Endwhile                                                        |
  1875. |                                                                      |
  1876. |    - Replace current with next data list pointer.                    |
  1877. |                                                                      |
  1878. |   Endwhile                                                           |
  1879. |                                                                      |
  1880. | - Return to the caller.                                              |
  1881. |                                                                      |
  1882. +=====================================================================*/
  1883. /*====================================================================*/
  1884. /* internal function ListResult (build the result information)        */
  1885. /*====================================================================*/
  1886. INT    ListResult                      /* access the result list      */
  1887.        (
  1888.         PVOID     pSession,            /* In  -- session pointer      */
  1889.         ULONG     ulResultHandle,      /* In  -- result handle        */
  1890.         ULONG     ulResultSize,        /* In  -- result size          */
  1891.         ULONG     ulReferenceLimit,    /* In  -- reference limit      */
  1892.         PXTBL     pIndexTable          /* In  -- index table          */
  1893.        )                               /* function value: status code */
  1894. {                                      /* function variables:         */
  1895.    ULONG     ulReturnCode    = RC_DONE;/* API return code             */
  1896.    ULONG     ulDiagnosisInfo = 0L;     /* API diagnosis information   */
  1897.    ULONG     ulDataLength    = 0L;     /* API datastream length       */
  1898.    PCHAR     pDataStream     = NULL;   /* API datastream pointer      */
  1899.    PCHAR     pDataEnd        = NULL;   /* end of datastream pointer   */
  1900.    PPRESULT  ppResult        = NULL;   /* result information pointer  */
  1901.    PITEM     *pDocument      = NULL;   /* ptr to document item ptr    */
  1902.    PITEM     *pIndexItem     = NULL;   /* ptr to index item ptr       */
  1903.    PITEM     *pRankValue     = NULL;   /* ptr to document rank value  */
  1904.    PITEM     *pRankCount     = NULL;   /* ptr to document rank count  */
  1905.    PITEM     *pWordCount     = NULL;   /* ptr to overall no of words  */
  1906.    LIST      List;                     /* work data list structure    */
  1907.    PLIST     pList           = &List;  /* current data list pointer   */
  1908.    PINDEX    pIndex          = NULL;   /* pointer to Index information*/
  1909.    /*-----------------------------------------------------------------*/
  1910.    /* Determine number of document pointers in the result information */
  1911.    /*-----------------------------------------------------------------*/
  1912.    if (ulReferenceLimit > ulResultSize)
  1913.       ulReferenceLimit = ulResultSize;
  1914.    if (!ulReferenceLimit)              /* check if the limit is zero  */
  1915.       ulReferenceLimit = 1L;
  1916.                                        /* calculate result info. size */
  1917.    ulDataLength = offsetof(RESULT, pDocumentInfo) +
  1918.                   ulReferenceLimit * sizeof(DOCINFO);
  1919.  
  1920.    /*-----------------------------------------------------------------*/
  1921.    /* Allocate and initialize the result list information:            */
  1922.    /* free slot where to anchor result list information is determined */
  1923.    /* by variable usResultCount.                                      */
  1924.    /* Maximum number of slots is defined by LT_NUMBER_OF_RESULTS.     */
  1925.    /*-----------------------------------------------------------------*/
  1926.    ppResult = &pIndexTable->pResult[pIndexTable->usResultCount];
  1927.    *ppResult = (PRESULT )malloc((size_t )ulDataLength);
  1928.    if (!*ppResult)                     /* check if allocation failed  */
  1929.    {
  1930.       /*--------------------------------------------------------------*/
  1931.       /* handle the allocation error ...                              */
  1932.       /*--------------------------------------------------------------*/
  1933.       return (RC_FALSE);               /* return to the caller        */
  1934.    }                                   /* endif allocation failed     */
  1935.                                        /* write the header text       */
  1936.    memcpy((*ppResult)->Header, "RsltInfo", sizeof((*ppResult)->Header));
  1937.  
  1938.    (*ppResult)->ulInfoLength    = ulDataLength;
  1939.    (*ppResult)->ulHandle        = ulResultHandle;
  1940.    (*ppResult)->ulSize          = ulReferenceLimit;
  1941.    (*ppResult)->ulDataLength    = 0L;
  1942.    (*ppResult)->pData           = NULL;
  1943.    (*ppResult)->ulDocumentCount = 0L;
  1944.  
  1945.    /*-----------------------------------------------------------------*/
  1946.    /* initialize the (temporary) first data list structure            */
  1947.    /*-----------------------------------------------------------------*/
  1948.    memset(pList, 0x00, sizeof(List));
  1949.  
  1950.    /*-----------------------------------------------------------------*/
  1951.    /* access the result list information, by calling API service      */
  1952.    /* EhwGetResultList (until end of data is indicated)               */
  1953.    /*-----------------------------------------------------------------*/
  1954.    do
  1955.    {
  1956.       ulReturnCode =
  1957.       EhwGetResultList(pSession,       /* In  -- session pointer      */
  1958.                        ulResultHandle, /* In  -- result handle        */
  1959.                        &ulDataLength,  /* Out -- datastream length    */
  1960.                        &pDataStream,   /* Out -- index list           */
  1961.                        &ulDiagnosisInfo);/* Out -- diagnosis info.    */
  1962.  
  1963.       printf ("ReturnCode (EhwGetResultList)    = %d \n", ulReturnCode);
  1964.                                        /* check the API return code   */
  1965.       if ((ulReturnCode != RC_DONE) &&
  1966.           (ulReturnCode != RC_CONTINUATION_MODE_ENTERED))
  1967.       {
  1968.          /*-----------------------------------------------------------*/
  1969.          /* handle the function error ...                             */
  1970.          /*-----------------------------------------------------------*/
  1971.          if (List.pNextData)           /* check if a data list exists */
  1972.          {                             /* anchor present data lists   */
  1973.             (*ppResult)->pData = List.pNextData;
  1974.          }
  1975.          return (RC_FALSE);            /* return to the caller        */
  1976.       }                                /* endif API call failed       */
  1977.  
  1978.       /*--------------------------------------------------------------*/
  1979.       /* allocate a 'new' data list area, anchor it in the 'old' one  */
  1980.       /*--------------------------------------------------------------*/
  1981.       pList->pNextData = (PLIST )
  1982.                          malloc((size_t )(offsetof(LIST, Data[0])
  1983.                                           + ulDataLength));
  1984.  
  1985.       /*--------------------------------------------------------------*/
  1986.       /* update current data list pointer                             */
  1987.       /*--------------------------------------------------------------*/
  1988.       pList = pList->pNextData;        /* replace old with new ptr    */
  1989.  
  1990.       if (!pList)                      /* check if allocation failed  */
  1991.       {
  1992.          /*-----------------------------------------------------------*/
  1993.          /* handle the allocation error ...                           */
  1994.          /*-----------------------------------------------------------*/
  1995.                                        /* anchor present data lists   */
  1996.          (*ppResult)->pData = List.pNextData;
  1997.          return (RC_FALSE);            /* return to the caller        */
  1998.       }                                /* endif allocation failed     */
  1999.  
  2000.       /*--------------------------------------------------------------*/
  2001.       /* save current result list block in the list data area         */
  2002.       /*--------------------------------------------------------------*/
  2003.       pList->pNextData    = NULL;
  2004.       pList->ulDataLength = ulDataLength;
  2005.       memcpy(pList->Data, pDataStream, (size_t )ulDataLength);
  2006.  
  2007.       /*--------------------------------------------------------------*/
  2008.       /* update total result list data length                         */
  2009.       /*--------------------------------------------------------------*/
  2010.       (*ppResult)->ulDataLength += ulDataLength;
  2011.  
  2012.    }  while (ulReturnCode == RC_CONTINUATION_MODE_ENTERED);
  2013.  
  2014.    /*-----------------------------------------------------------------*/
  2015.    /* anchor first data list area in the result information           */
  2016.    /*-----------------------------------------------------------------*/
  2017.    (*ppResult)->pData = List.pNextData;
  2018.  
  2019.    /*-----------------------------------------------------------------*/
  2020.    /* increase number of result lists                                 */
  2021.    /*-----------------------------------------------------------------*/
  2022.    pIndexTable->usResultCount++;
  2023.  
  2024.    /*-----------------------------------------------------------------*/
  2025.    /* set the document pointers (references) in the                   */
  2026.    /* result information by parsing the chained result list data      */
  2027.    /*-----------------------------------------------------------------*/
  2028.    if (!ulReferenceLimit)              /* check the reference limit   */
  2029.       return (RC_TRUE);
  2030.                                        /* start at first document ptr */
  2031.    pDocument  = &((*ppResult)->pDocumentInfo->pDocument);
  2032.    pIndexItem = &((*ppResult)->pDocumentInfo->pIndex);
  2033.    pRankValue = &((*ppResult)->pDocumentInfo->pRankValue);
  2034.    pRankCount = &((*ppResult)->pDocumentInfo->pRankCount);
  2035.    pWordCount = &((*ppResult)->pDocumentInfo->pWordCount);
  2036.    pList      = (*ppResult)->pData;    /* reset current data list ptr */
  2037.    while (pList)                       /* check if end of total       */
  2038.    {                                   /* result list data is reached */
  2039.       ulDataLength = pList->ulDataLength;
  2040.       pDataStream  = (PCHAR )pList->Data;
  2041.                                        /* set the ptr to end of block */
  2042.       pDataEnd = pDataStream + ulDataLength;
  2043.  
  2044.       /*--------------------------------------------------------------*/
  2045.       /* parse current result list block until end of data (block)    */
  2046.       /* or the document reference limit is reached                   */
  2047.       /*--------------------------------------------------------------*/
  2048.       while (pDataStream < pDataEnd)
  2049.       {                                /* check the item identifier   */
  2050.          switch( ((PITEM )pDataStream)->id)
  2051.          {                             /* overcome big-endian format  */
  2052.                                        /* using macro ID()            */
  2053.  
  2054.            case( ID(ID_DOC) ):         /* document delimiter item     */
  2055.             /*--------------------------------------------------------*/
  2056.             /* ID_DOC delimits each document information              */
  2057.             /* when the document reference limit is reached stop      */
  2058.             /* parsing the data stream                                */
  2059.             /*--------------------------------------------------------*/
  2060.              if( ((PITEM )pDataStream)->it == IT_END )
  2061.              {
  2062.                 if (!((*ppResult)->ulDocumentCount < ulReferenceLimit))
  2063.                    return (RC_TRUE);   /* return to the caller        */
  2064.  
  2065.                /*-----------------------------------------------------*/
  2066.                /* increase DocumentInfo structure and set pointer     */
  2067.                /* to structure elements                               */
  2068.                /*-----------------------------------------------------*/
  2069.                 (*ppResult)->pDocumentInfo++;
  2070.  
  2071.                 pDocument  = &((*ppResult)->pDocumentInfo->pDocument);
  2072.                 pIndexItem = &((*ppResult)->pDocumentInfo->pIndex);
  2073.                 pRankValue = &((*ppResult)->pDocumentInfo->pRankValue);
  2074.                 pRankCount = &((*ppResult)->pDocumentInfo->pRankCount);
  2075.                 pWordCount = &((*ppResult)->pDocumentInfo->pWordCount);
  2076.              }
  2077.             break;
  2078.  
  2079.            case( ID(ID_XNAM) ):        /* index identifier item:      */
  2080.             /*--------------------------------------------------------*/
  2081.             /* save address of current index identifier item          */
  2082.             /*--------------------------------------------------------*/
  2083.               *pIndexItem = (PITEM )pDataStream;
  2084.  
  2085.             break;
  2086.  
  2087.            case( ID(ID_DID) ):         /* document identifier item:   */
  2088.             /*--------------------------------------------------------*/
  2089.             /* save address of current document identifier item       */
  2090.             /* and address of corresponding index identifier item     */
  2091.             /* increase counter in the result information structure   */
  2092.             /*--------------------------------------------------------*/
  2093.             *pDocument = (PITEM )pDataStream;
  2094.             (*ppResult)->ulDocumentCount++;
  2095.  
  2096.            break;
  2097.  
  2098.            case( ID(ID_RVAL) ):        /* rank value item:            */
  2099.             /*--------------------------------------------------------*/
  2100.             /* save address of rank value                             */
  2101.             /*--------------------------------------------------------*/
  2102.             *pRankValue = (PITEM )pDataStream;
  2103.  
  2104.            break;
  2105.  
  2106.            case( ID(ID_RCNT) ):        /* rank count item:            */
  2107.             /*--------------------------------------------------------*/
  2108.             /* save address of rank count                             */
  2109.             /*--------------------------------------------------------*/
  2110.             *pRankCount = (PITEM )pDataStream;
  2111.  
  2112.            break;
  2113.  
  2114.            case( ID(ID_DSIZE) ):       /* number of words item        */
  2115.             /*--------------------------------------------------------*/
  2116.             /* save address of overall number of words                */
  2117.             /*--------------------------------------------------------*/
  2118.             *pWordCount = (PITEM )pDataStream;
  2119.  
  2120.            break;
  2121.          }                             /* end switch datastream items */
  2122.  
  2123.                                        /* skip current data item      */
  2124.          /*-----------------------------------------------------------*/
  2125.          /* invert 'big-endian' to 'intel' format using macro VAL2()  */
  2126.          /*-----------------------------------------------------------*/
  2127.          pDataStream += VAL2(&(((PITEM )pDataStream)->ll));
  2128.  
  2129.       }                                /* endwhile not end of list    */
  2130.       pList = pList->pNextData;        /* skip current data list      */
  2131.    }                                   /* endwhile not end of result  */
  2132.    return (RC_TRUE);
  2133. }                                      /* end of ListResult()         */
  2134.  
  2135. /*=====================================================================+
  2136. |                                                                      |
  2137. | Entry point:  DeleteResults                                          |
  2138. |                                                                      |
  2139. | Function:     Deletes the search result.                             |
  2140. |               Result lists created by API calls EhwCreateResultList  |
  2141. |               EhwSelectResultList are also deleted.                  |
  2142. |                                                                      |
  2143. | Input                                                                |
  2144. | parameters:   Session pointer                                        |
  2145. |               Search result handle                                   |
  2146. |               Index Table                                            |
  2147. |                                                                      |
  2148. | Output                                                               |
  2149. | parameters:   Index Table                                            |
  2150. |                                                                      |
  2151. | Return codes: Status ok         RC_TRUE                              |
  2152. |               Status not ok     RC_FALSE                             |
  2153. |                                                                      |
  2154. | Input files:  None                                                   |
  2155. |                                                                      |
  2156. | Output files: None                                                   |
  2157. |                                                                      |
  2158. |                                                                      |
  2159. | Calls:        API functions:                                         |
  2160. |                                                                      |
  2161. |                   EhwDeleteResult                                    |
  2162. |                                                                      |
  2163. | Exits:        Returns to caller                                      |
  2164. |                                                                      |
  2165. |----------------------------------------------------------------------|
  2166. |                                                                      |
  2167. | Program logic:                                                       |
  2168. |                                                                      |
  2169. | - Issue an EhwDeleteResult function call to delete the               |
  2170. |   current search result and related result lists.                    |
  2171. | - Check the API function return code.                                |
  2172. |                                                                      |
  2173. | - Free the result list datastreams (chained data list areas).        |
  2174. |                                                                      |
  2175. | - Release the chained result lists.                                  |
  2176. |                                                                      |
  2177. |                                                                      |
  2178. | - Return to the caller.                                              |
  2179. |                                                                      |
  2180. +=====================================================================*/
  2181. /*====================================================================*/
  2182. /* internal function DeleteResults (release the result information)   */
  2183. /*====================================================================*/
  2184. INT    DeleteResults                   /* delete current result info. */
  2185.        (
  2186.         PVOID     pSession,            /* In  -- session pointer      */
  2187.         ULONG     ulResultHandle,      /* In  -- search result handle */
  2188.         PXTBL     pIndexTable          /* In/Out index information    */
  2189.        )                               /* function value: status code */
  2190. {                                      /* function variables:         */
  2191.    ULONG     ulReturnCode    = RC_DONE;/* API return code             */
  2192.    ULONG     ulResListHandle = 0L;     /* API result handle           */
  2193.    ULONG     ulDiagnosisInfo = 0L;     /* API diagnosis information   */
  2194.    INT       iStatus         = RC_TRUE;/* work data list structure    */
  2195.    PLIST     pList           = NULL;   /* current data list pointer   */
  2196.    PLIST     pNext           = NULL;   /* next data list pointer      */
  2197.                                        /* result information pointer  */
  2198.  
  2199.    /*-----------------------------------------------------------------*/
  2200.    /* Call API EhwDeleteResult to delete the search result.           */
  2201.    /* All related result lists are also deleted.                      */
  2202.    /*-----------------------------------------------------------------*/
  2203.     ulReturnCode =
  2204.     EhwDeleteResult  (pSession,      /* In  -- session pointer      */
  2205.                      ulResultHandle, /* In  -- result handle        */
  2206.                      &ulDiagnosisInfo/* Out -- diagnosis info       */
  2207.                     );
  2208.     printf ("ReturnCode (EhwDeleteResult)     = %d \n", ulReturnCode);
  2209.  
  2210.     if (ulReturnCode != RC_DONE)     /* check the API return code   */
  2211.     {
  2212.        /*-----------------------------------------------------------*/
  2213.        /* handle the function error ...                             */
  2214.        /*-----------------------------------------------------------*/
  2215.        iStatus = RC_FALSE;           /* set function status code    */
  2216.     }                                /* endif API function failed   */
  2217.    /*-----------------------------------------------------------------*/
  2218.    /* Free the result list datastreams anchored in the result         */
  2219.    /* information in the index group table.                           */
  2220.    /*-----------------------------------------------------------------*/
  2221.    for(; pIndexTable->usResultCount > 0; pIndexTable->usResultCount--)
  2222.    {
  2223.                                        /* set first data list pointer */
  2224.      pList = pIndexTable->pResult[pIndexTable->usResultCount-1]->pData;
  2225.      while (pList)                     /* while not end of data lists */
  2226.      {
  2227.        pNext = pList->pNextData;       /* save next data list pointer */
  2228.        free(pList);                    /* release current data list   */
  2229.        pList = pNext;                  /* update pointer to data list */
  2230.      }                                 /* endwhile data list exists   */
  2231.  
  2232.      /*---------------------------------------------------------------*/
  2233.      /* release current result information area                       */
  2234.      /*---------------------------------------------------------------*/
  2235.      free(pIndexTable->pResult[pIndexTable->usResultCount - 1]);
  2236.    }
  2237.  
  2238.    return (iStatus);                   /* return to the caller        */
  2239. }                                      /* end of DeleteResult()       */
  2240.  
  2241. /*=====================================================================+
  2242. |                                                                      |
  2243. |  Entry point:  GetProblemInfo                                        |
  2244. |                                                                      |
  2245. |  Function:     Calls API EhwGetProblemInfo to get index specific     |
  2246. |                error codes.                                          |
  2247. |                                                                      |
  2248. |                Loops through datastream and copies index names       |
  2249. |                and corresponding return codes to application         |
  2250. |                memory.                                               |
  2251. |                                                                      |
  2252. |  Input                                                               |
  2253. |  parameters:   - Session pointer                                     |
  2254. |                - Result Handle (returned by API EhwSearch)           |
  2255. |                - Address of pointer to IndexProblemTable             |
  2256. |  Output                                                              |
  2257. |  parameters:   - Updated IndexProblemTable                           |
  2258. |                                                                      |
  2259. |  Return codes: Check ok         RC_TRUE                              |
  2260. |                Check not ok     RC_FALSE                             |
  2261. |                                                                      |
  2262. |  Calls:                                                              |
  2263. |                                                                      |
  2264. |               API function:                                          |
  2265. |                                                                      |
  2266. |                   EhwGetProblemInfo                                  |
  2267. |                                                                      |
  2268. |  Exits:        Returns to caller.                                    |
  2269. |                                                                      |
  2270. +=====================================================================*/
  2271. /*====================================================================*/
  2272. /* internal function GetProblemInfo                                   */
  2273. /*====================================================================*/
  2274. INT    GetProblemInfo
  2275.        (
  2276.         PVOID     pSession,            /* In  -- session pointer      */
  2277.         ULONG     ulResultHandle,      /* In  -- result handle        */
  2278.         PPBLTBL   *pProblemInfo        /* Out -- index problem info   */
  2279.        )
  2280. {
  2281.  ULONG     ulReturnCode    = 0L;       /* API return code             */
  2282.  ULONG     ulDiagnosisInfo = 0L;       /* API diagnosis information   */
  2283.  ULONG     ulDataLength    = 0L;       /* API datastream length       */
  2284.  PCHAR     pDataStream     = NULL;     /* API datastream pointer      */
  2285.  PCHAR     pDataEnd        = NULL;     /* API datastream pointer      */
  2286.  PCHAR     IndexName;
  2287.    INT     iCount          = 0;        /* loop variable               */
  2288.  PPBLTBL   pProblem;                   /* Out -- index problem info   */
  2289.  
  2290.  /*-------------------------------------------------------------------*/
  2291.  /* call API EhwGetProblemInfo                                        */
  2292.  /*-------------------------------------------------------------------*/
  2293.  ulReturnCode = EhwGetProblemInfo (
  2294.                       pSession,        /* In  -- session pointer      */
  2295.                       ulResultHandle,  /* In  -- result handle        */
  2296.                       &ulDataLength,   /* Out -- length of datastream */
  2297.                       &pDataStream,    /* Out -- datastream           */
  2298.                       &ulDiagnosisInfo /* Out -- diagnosis info       */
  2299.                         );             /* function value: return_code */
  2300.  
  2301.  if( ulReturnCode ) return(RC_FALSE);
  2302.  
  2303.   pDataEnd = pDataStream + ulDataLength;
  2304.   pProblem = *pProblemInfo;
  2305.   pProblem = NULL;
  2306.  /*-------------------------------------------------------------------*/
  2307.  /* if data was returned allocate an index problem table              */
  2308.  /*-------------------------------------------------------------------*/
  2309.   if (ulDataLength)
  2310.   {
  2311.      ulDataLength = (offsetof(PBLTBL, IdxProblem[0]) +
  2312.                      LT_NUMBER_OF_INDEXES * sizeof(INDEXPBL));
  2313.      pProblem = (PPBLTBL )malloc((size_t )ulDataLength);
  2314.  
  2315.      if (!pProblem)                    /* check if allocation failed  */
  2316.      {
  2317.       /*--------------------------------------------------------------*/
  2318.       /* handle the allocation error ...                              */
  2319.       /*--------------------------------------------------------------*/
  2320.       return (RC_FALSE);               /* return to the caller        */
  2321.      }
  2322.  
  2323.       memcpy(pProblem->Header,
  2324.              "PrblmTbl", sizeof(pProblem->Header));
  2325.                                        /* set table length            */
  2326.       pProblem->ulTableLength = ulDataLength;
  2327.                                        /* init. the number of slots   */
  2328.       pProblem->usTableEntries = 0;
  2329.   }
  2330.  
  2331.  /*-------------------------------------------------------------------*/
  2332.  /* loop through datastream and get index name and index specific     */
  2333.  /* return code                                                       */
  2334.  /*-------------------------------------------------------------------*/
  2335.   while(pDataStream < pDataEnd)
  2336.   {
  2337.     switch (((PITEM )pDataStream)->id)
  2338.     {                                 /* overcome big-endian format  */
  2339.                                       /* using macro ID()            */
  2340.          case ID(ID_IRX):             /* index delimiter             */
  2341.  
  2342.                                     /* check if it is an end item  */
  2343.            if (((PITEM )pDataStream)->it == IT_END)
  2344.                                     /* increase element counter    */
  2345.              iCount++;
  2346.  
  2347.          break;
  2348.  
  2349.          case ID(ID_XNAM):             /* index name item          */
  2350.  
  2351.             /*--------------------------------------------------------*/
  2352.             /* allocate memory and copy index name                    */
  2353.             /*--------------------------------------------------------*/
  2354.             IndexName = (&pProblem->IdxProblem[iCount])->IndexName;
  2355.             ulDataLength =  ((PITEM )pDataStream)->ll - 5 + 1;
  2356.             IndexName = (PCHAR)malloc((size_t )ulDataLength);
  2357.             if (!IndexName)            /* check if allocation failed  */
  2358.                 return (RC_FALSE);     /* return to the caller        */
  2359.  
  2360.             (&pProblem->IdxProblem[iCount])->IndexName = IndexName;
  2361.  
  2362.             memcpy(IndexName,
  2363.                    ((PITEM )pDataStream)->value,
  2364.                    ((PITEM )pDataStream)->ll - 5 );
  2365.  
  2366.             break;
  2367.  
  2368.          case ID(ID_XRC):              /* index specific return code  */
  2369.  
  2370.             /*--------------------------------------------------------*/
  2371.             /* copy index specific return code                        */
  2372.             /*--------------------------------------------------------*/
  2373.             (&pProblem->IdxProblem[iCount])->usProblemRc =
  2374.                              (USHORT)VAL2(((PITEM )pDataStream)->value);
  2375.             break;
  2376.  
  2377.          default:
  2378.                                        /* skip all unknown data items */
  2379.             break;
  2380.       }                                /* endswitch item identifier   */
  2381.                                        /* skip current data item      */
  2382.       /*--------------------------------------------------------------*/
  2383.       /* invert big-endian format using macro VAL2()                  */
  2384.       /*--------------------------------------------------------------*/
  2385.       pDataStream += VAL2(&(((PITEM )pDataStream)->ll));
  2386.    }                                   /* endwhile not end of data    */
  2387.  
  2388.    *pProblemInfo = pProblem;
  2389.    return (RC_TRUE);
  2390. }
  2391. /*=====================================================================+
  2392. |                                                                      |
  2393. | Entry point:  HandleExit                                             |
  2394. |                                                                      |
  2395. | Function:     Exit function of the sample main routine.              |
  2396. |               Releases the storage acquired by the sample            |
  2397. |               application program and ends pending sessions.         |
  2398. |                                                                      |
  2399. | Input                                                                |
  2400. | parameters:   Pointer to server table                                |
  2401. |               Pointer to work area                                   |
  2402. |                                                                      |
  2403. | Output                                                               |
  2404. | parameters:   None                                                   |
  2405. |                                                                      |
  2406. | Return codes: None                                                   |
  2407. |                                                                      |
  2408. | Input files:  None                                                   |
  2409. |                                                                      |
  2410. | Output files: None                                                   |
  2411. |                                                                      |
  2412. |                                                                      |
  2413. | Calls:        API functions:                                         |
  2414. |                                                                      |
  2415. |                   EhwEndSession                                      |
  2416. |                                                                      |
  2417. | Exits:        Returns to caller                                      |
  2418. |                                                                      |
  2419. |----------------------------------------------------------------------|
  2420. |                                                                      |
  2421. | Program logic:                                                       |
  2422. |                                                                      |
  2423. | - If the server table exists                                         |
  2424. |                                                                      |
  2425. |    - Do for all server information entries:                          |
  2426. |                                                                      |
  2427. |       - If there is a pending session                                |
  2428. |                                                                      |
  2429. |          - Issue an EhwEndSession function call to terminate the     |
  2430. |            session with the current server.                          |
  2431. |                                                                      |
  2432. |         Endif                                                        |
  2433. |                                                                      |
  2434. |       - If the index table exists                                    |
  2435. |                                                                      |
  2436. |          - Do for all index information entries:                     |
  2437. |                                                                      |
  2438. |             - Release all anchored result information data.          |
  2439. |             - Free the current index information.                    |
  2440. |                                                                      |
  2441. |            Enddo                                                     |
  2442. |                                                                      |
  2443. |          - Release the index table.                                  |
  2444. |                                                                      |
  2445. |         Endif                                                        |
  2446. |                                                                      |
  2447. |      Enddo                                                           |
  2448. |                                                                      |
  2449. |    - Release the server table.                                       |
  2450. |                                                                      |
  2451. |   Endif                                                              |
  2452. |                                                                      |
  2453. | - Free the work area.                                                |
  2454. |                                                                      |
  2455. | - Return to the caller.                                              |
  2456. |                                                                      |
  2457. +=====================================================================*/
  2458. /*====================================================================*/
  2459. /* internal function HandleExit (release allocated storage)           */
  2460. /*====================================================================*/
  2461. VOID   HandleExit                      /* clear up function for main  */
  2462.        (
  2463.         PSRVTBL   pServerTable,        /* In  -- server table pointer */
  2464.         PCHAR     pArea                /* In  -- work area pointer    */
  2465.        )                               /* function value: none        */
  2466. {                                      /* function variables:         */
  2467.    ULONG     ulReturnCode    = RC_DONE;/* API return code             */
  2468.    ULONG     ulDiagnosisInfo = 0L;     /* API diagnosis information   */
  2469.    PVOID     pSession        = NULL;   /* API session pointer         */
  2470.    PXTBL     pIndexTable     = NULL;   /* index table pointer         */
  2471.    PSERVER   pServer         = NULL;   /* server information pointer  */
  2472.    PINDEX    pIndex          = NULL;   /* index information pointer   */
  2473.    PRESULT   pResult         = NULL;   /* result information pointer  */
  2474.    PLIST     pList           = NULL;   /* data list pointer           */
  2475.    PLIST     pNext           = NULL;   /* data list pointer           */
  2476.    INT       iCount          = 0;      /* loop variable               */
  2477.    /*-----------------------------------------------------------------*/
  2478.    /* release storage allocated outside a session                     */
  2479.    /*-----------------------------------------------------------------*/
  2480.    if (pServerTable)                   /* check the server table ptr  */
  2481.    {
  2482.       pServer = pServerTable->Server;  /* initialize server info. ptr */
  2483.       while (pServerTable->usServerCount)
  2484.       {
  2485.          /*-----------------------------------------------------------*/
  2486.          /* free session related storage allocated by API functions   */
  2487.          /*-----------------------------------------------------------*/
  2488.          pSession = pServer->pSession; /* set first session pointer   */
  2489.          if (pSession)                 /* check if session is started */
  2490.          {                             /* end the API session         */
  2491.             ulReturnCode =
  2492.             EhwEndSession (pSession,   /* In  -- session pointer      */
  2493.                                        /* Out -- diagnosis info       */
  2494.                            &ulDiagnosisInfo);
  2495.  
  2496.             printf ("ReturnCode (EhwEndSession)       = %d \n",
  2497.                     ulReturnCode);
  2498.          }
  2499.          /*-----------------------------------------------------------*/
  2500.          /* free session related storage acquired by sample functions */
  2501.          /*-----------------------------------------------------------*/
  2502.                                        /* check if index group exists */
  2503.          if (pServer->pGroupTable)
  2504.           free (pServer->pGroupTable); /* free index group table      */
  2505.  
  2506.          pIndexTable = pServer->pIndexTable;
  2507.          if (pIndexTable)              /* check if index table exists */
  2508.          {
  2509.             for(; iCount < pIndexTable->usResultCount; iCount++)
  2510.             {
  2511.               pResult = pIndexTable->pResult[iCount];
  2512.               if (pResult)             /* check result info. pointer  */
  2513.               {                        /* set first data list pointer */
  2514.                 pList = pResult->pData;
  2515.                 while (pList)          /* while not end of data lists */
  2516.                 {                      /* save next data list pointer */
  2517.                   pNext = pList->pNextData;
  2518.                   free(pList);         /* release current data list   */
  2519.                   pList = pNext;       /* update pointer to data list */
  2520.                 }                      /* endwhile data list exists   */
  2521.                   free(pResult);       /* free result information     */
  2522.               }
  2523.             }
  2524.  
  2525.             for(iCount=0; iCount<pIndexTable->usIndexCount; iCount++)
  2526.                                        /* release current index info. */
  2527.                free(pIndexTable->pIndex[iCount]);
  2528.  
  2529.             free(pIndexTable);         /* release the index table     */
  2530.          }
  2531.                                        /* update server info. pointer */
  2532.          pServer = (PSERVER )
  2533.                    ((PCHAR )pServer + (offsetof(SERV, Name)
  2534.                                        + pServer->usNameLength));
  2535.          (pServerTable->usServerCount)--;
  2536.       }
  2537.       free(pServerTable);              /* release the server table    */
  2538.    }
  2539.    if (pArea)  free(pArea);            /* release the work area       */
  2540.  
  2541.    return;                             /* return to the caller        */
  2542. }                                      /* end of HandleError()        */
  2543.  
  2544. /*=====================================================================+
  2545. |                                                                      |
  2546. |  Entry point:  WriteDataStream                                       |
  2547. |                                                                      |
  2548. |  Function:     Writes a specified datastream item to the provided    |
  2549. |                area.                                                 |
  2550. |                                                                      |
  2551. |                It is checked, if the item fits into the remaining    |
  2552. |                buffer space (if yes, the length of the remaining     |
  2553. |                space and corresponding pointer are updated).         |
  2554. |                                                                      |
  2555. |                Conversion of USHORT variables between 'intel' and    |
  2556. |                'big-endian' formats is done within this function     |
  2557. |                for two-byte identifiers and lengths using VAL2       |
  2558. |                macro. The item values are written as provided.       |
  2559. |  Input                                                               |
  2560. |  parameters:   - Item identifier                                     |
  2561. |                - Item type                                           |
  2562. |                - Length of item value (may be zero)                  |
  2563. |                - Item value (optional)                               |
  2564. |                - Length of remaining space                           |
  2565. |                - Pointer to remaining space                          |
  2566. |  Output                                                              |
  2567. |  parameters:   - Updated length of remaining space  (for RC_TRUE)    |
  2568. |                - Updated pointer to remaining space (for RC_TRUE)    |
  2569. |                                                                      |
  2570. |  Return codes: Check ok         RC_TRUE                              |
  2571. |                Check not ok     RC_FALSE                             |
  2572. |                                                                      |
  2573. |  Exits:        Returns to caller.                                    |
  2574. |                                                                      |
  2575. +=====================================================================*/
  2576. /*====================================================================*/
  2577. /* internal function WriteDataItem (write datastream item)            */
  2578. /*====================================================================*/
  2579. INT    WriteDataItem
  2580.        (
  2581.         USHORT    usItemId,            /* In  -- item identifier      */
  2582.         UCHAR     ItemType,            /* In  -- item type            */
  2583.         USHORT    usValueLength,       /* In  -- length of item value */
  2584.         PCHAR     pValue,              /* In  -- ptr to item value    */
  2585.         PULONG    pulAreaLength,       /* In/Out remaining area size  */
  2586.         PPCHAR    ppArea               /* In/Out ptr to target area   */
  2587.        )
  2588. {
  2589.    USHORT         usItemLL;            /* total length of data item   */
  2590.    PITEM          pItem;               /* pointer to data stream item */
  2591.  
  2592.    pItem    = (PITEM )*ppArea;         /* set pointer to target area  */
  2593.                                        /* calculate total item length */
  2594.    usItemLL = offsetof(ITEM, value[0]) + usValueLength;
  2595.                                        /* check remaining area length */
  2596.    if ((ULONG )usItemLL > *pulAreaLength)  return (RC_FALSE);
  2597.                                        /* write item ll/id/it to area */
  2598.    pItem->ll = VAL2(&usItemLL);        /* invertion to big-endian     */
  2599.    pItem->id = VAL2(&usItemId);        /* format using macro VAL2()   */
  2600.    pItem->it = ItemType;
  2601.                                        /* if provided, write          */
  2602.    if (usValueLength)                  /* item value to target area   */
  2603.       memcpy(pItem->value, pValue, (size_t )usValueLength);
  2604.  
  2605.    *ppArea        += usItemLL;         /* update current area pointer */
  2606.    *pulAreaLength -= usItemLL;         /* update remaining area len.  */
  2607.  
  2608.    return (RC_TRUE);
  2609. }                                      /* end of WriteDataItem()      */
  2610.  
  2611. /*====================================================================*/
  2612.