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

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