home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR41 / CBASE11.ZIP / CBKEYSRC.C < prev    next >
C/C++ Source or Header  |  1993-01-01  |  4KB  |  179 lines

  1. /*
  2.  *    Copyright (c) 1989-1992 Citadel Software, Inc.
  3.  *    All Rights Reserved
  4.  */
  5.  
  6. /* #ident    "@(#)cbkeysrc.c    1.7 - 93/01/01" */
  7.  
  8. #include <port.h>
  9.  
  10. /* standard headers */
  11. #include <errno.h>
  12. #ifdef AC_STDDEF
  13. #include <stddef.h>
  14. #endif
  15. #ifdef AC_STDLIB
  16. #include <stdlib.h>
  17. #endif
  18. #ifdef AC_STRING
  19. #include <string.h>
  20. #endif
  21.  
  22. /* library headers */
  23. #include <blkio.h>
  24. #include <bool.h>
  25. #include <btree.h>
  26. #include <lseq.h>
  27. #include <xtend.h>
  28.  
  29. /* local headers */
  30. #include "cbase_.h"
  31.  
  32. /*man---------------------------------------------------------------------------
  33. NAME
  34.      cbkeysrch - search cbase key
  35.  
  36. SYNOPSIS
  37.      #include <cbase.h>
  38.  
  39.      int cbkeysrch(cbp, field, buf)
  40.      cbase_t *cbp;
  41.      int field;
  42.      const void *buf;
  43.  
  44. DESCRIPTION
  45.      The cbkeysrch function searches a key in cbase cbp.  field is the
  46.      field to be searched.  buf points to the key for which to be
  47.      searched.  If found, the cursor for that key is positioned to the
  48.      found key.  If it is not found, the cursor for that key is
  49.      positioned to the next higher key, which may be null.  The record
  50.      cursor is set to the record associated with the key marked by the
  51.      key cursor.  Other key cursors are not affected.
  52.  
  53.      cbkeysrch will fail if one or more of the following is true:
  54.  
  55.      [EINVAL]       cbp is not a valid cbase pointer.
  56.      [EINVAL]       field is not a valid field number for
  57.                     cbase cbp.
  58.      [EINVAL]       buf is the NULL pointer.
  59.      [CBELOCK]      cbp is not read locked.
  60.      [CBENKEY]      field is not a key.
  61.      [CBENOPEN]     cbp is not open.
  62.  
  63. SEE ALSO
  64.      cbkcursor, cbkeyfirst, cbkeylast, cbkeynext, cbkeyprev.
  65.  
  66. DIAGNOSTICS
  67.      Upon successful completion, a value of 1 is returned if the key
  68.      was found or a value of 0 if it was not.  Otherwise, a value of
  69.      -1 is returned, and errno set to indicate the error.
  70.  
  71. ------------------------------------------------------------------------------*/
  72. #ifdef AC_PROTO
  73. int cbkeysrch(cbase_t *cbp, int field, const void *buf)
  74. #else
  75. int cbkeysrch(cbp, field, buf)
  76. cbase_t *cbp;
  77. int field;
  78. const void *buf;
  79. #endif
  80. {
  81.     void *    buf2    = NULL;
  82.     cbrpos_t cbrpos    = NIL;
  83.     lspos_t    lspos    = NIL;
  84.     bool    found    = FALSE;
  85.  
  86.     /* validate arguments */
  87.     if (!cb_valid(cbp) || buf == NULL) {
  88.         errno = EINVAL;
  89.         return -1;
  90.     }
  91.  
  92.     /* check if not open */
  93.     if (!(cbp->flags & CBOPEN)) {
  94.         errno = CBENOPEN;
  95.         return -1;
  96.     }
  97.  
  98.     /* validate arguments */
  99.     if (field < 0 || field >= cbp->fldc) {
  100.         errno = EINVAL;
  101.         return -1;
  102.     }
  103.  
  104.     /* check if field is a key */
  105.     if (!(cbp->fldv[field].flags & CB_FKEY)) {
  106.         errno = CBENKEY;
  107.         return -1;
  108.     }
  109.  
  110.     /* check if not read locked */
  111.     if (!(cbp->flags & CBRDLCK)) {
  112.         errno = CBELOCK;
  113.         return -1;
  114.     }
  115.  
  116.     /* construct (key, record position) pair */
  117.     if (btkeysize(cbp->btpv[field]) != (cbp->fldv[field].len + sizeof(cbrpos_t))) {
  118.         CBERRLOG;
  119.         errno = CBEFATAL;
  120.         return -1;
  121.     }
  122.     buf2 = xcalloc((size_t)1, cbp->fldv[field].len + sizeof(cbrpos_t));
  123.     if (buf2 == NULL) {
  124.         CBERRLOG;
  125.         errno = ENOMEM;
  126.         return -1;
  127.     }
  128.     cbrpos = NIL;
  129.     memcpy(buf2, buf, cbp->fldv[field].len);
  130.     memcpy((char *)buf2 + cbp->fldv[field].len, &cbrpos, sizeof(cbrpos_t));
  131.  
  132.     /* search for key */
  133.     if (btsearch(cbp->btpv[field], buf2) == -1) {
  134.         CBERRLOG;
  135.         xfree(buf2);
  136.         return -1;
  137.     }
  138.  
  139.     /* check if cursor is null */
  140.     if (btcursor(cbp->btpv[field]) == NULL) {
  141.         xfree(buf2);
  142.         if (lssetcur(cbp->lsp, NULL) == -1) {
  143.             CBERRLOG;
  144.             return -1;
  145.         }
  146.         return 0;
  147.     }
  148.  
  149.     /* get record position */
  150.     if (btgetk(cbp->btpv[field], buf2) == -1) {
  151.         CBERRLOG;
  152.         xfree(buf2);
  153.         return -1;
  154.     }
  155.     memcpy(&cbrpos, (char *)buf2 + cbp->fldv[field].len, sizeof(cbrpos));
  156.  
  157.     /* check if key found or not */
  158.     if ((*cbcmpv[cbp->fldv[field].type])(buf, buf2, cbp->fldv[field].len) == 0) {
  159.         found = TRUE;
  160.     } else {
  161.         found = FALSE;
  162.     }
  163.     xfree(buf2);
  164.     buf2 = NULL;
  165.  
  166.     /* set record cursor */
  167.     lspos = cbrpos;
  168.     if (lspos == NIL) {
  169.         CBERRLOG;
  170.         errno = CBEFATAL;
  171.     }
  172.     if (lssetcur(cbp->lsp, &lspos) == -1) {
  173.         CBERRLOG;
  174.         return -1;
  175.     }
  176.  
  177.     return found ? 1 : 0;
  178. }
  179.