Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
5.0 KiB

  1. /*****************************************************************************
  2. * *
  3. * BTKTSZI.C *
  4. * *
  5. * Copyright (C) Microsoft Corporation 1989 - 1994. *
  6. * All Rights reserved. *
  7. * *
  8. ******************************************************************************
  9. * *
  10. * Module Intent *
  11. * *
  12. * Functions for SZI (0-terminated case insensitive string) keys. *
  13. * *
  14. ******************************************************************************
  15. * *
  16. * Current Owner: UNDONE *
  17. * *
  18. *****************************************************************************/
  19. static char s_aszModule[] = __FILE__; /* For error report */
  20. #include <mvopsys.h>
  21. #include <orkin.h>
  22. #include <misc.h>
  23. #include <iterror.h>
  24. #include <wrapstor.h>
  25. #include <mvsearch.h>
  26. #include <_mvutil.h>
  27. #include "common.h"
  28. /***************************************************************************
  29. *
  30. * @doc INTERNAL
  31. *
  32. * @func BK FAR PASCAL | BkScanSziInternal |
  33. * Scan an internal node for a key and return child BK.
  34. *
  35. * @parm BK | bk |
  36. * BK of internal node to scan
  37. *
  38. * @parm KEY | key |
  39. * key to search for
  40. *
  41. * @parm SHORT | wLevel |
  42. * level of btree bk lives on
  43. *
  44. * @parm QBTHR | qbthr |
  45. * btree header containing cache, and btree specs
  46. *
  47. * @parm QW | qiKey |
  48. * address of an int or NULL to not get it
  49. *
  50. * @parm QBTHR | qbthr |
  51. * qbthr->qCache - bk's block will be cached
  52. *
  53. * @parm QW | qiKey |
  54. * index into rgbBlock of first key >= key
  55. *
  56. * @rdesc bk of subtree that might contain key; bkNil on error
  57. * Side Effects: bk's block will be cached
  58. *
  59. ***************************************************************************/
  60. PUBLIC BK FAR PASCAL BkScanSziInternal(BK bk, KEY key, SHORT wLevel,
  61. QBTHR qbthr, QW qiKey, PHRESULT phr)
  62. {
  63. QCB qcb;
  64. QB q;
  65. SHORT cKeys;
  66. LPB lpLigatureTable;
  67. if ((qcb = QFromBk(bk, wLevel, qbthr, phr)) == NULL)
  68. {
  69. return bkNil;
  70. }
  71. q = qcb->db.rgbBlock;
  72. cKeys = qcb->db.cKeys;
  73. bk = (BK)GETLONG(q);
  74. q += sizeof(BK);
  75. lpLigatureTable = (LPB)(((LPCHARTAB)*qbthr->lrglpCharTab)->lpLigature);
  76. while (cKeys-- > 0)
  77. {
  78. if (WCmpiSz((SZ)key, (SZ)q, lpLigatureTable) >= 0)
  79. {
  80. q += STRLEN((SZ)q) + 1;
  81. bk = GETLONG(q);
  82. q += sizeof(BK);
  83. }
  84. else
  85. break;
  86. }
  87. if (qiKey != NULL)
  88. {
  89. *qiKey = (WORD)(q - (QB)qcb->db.rgbBlock);
  90. }
  91. return bk;
  92. }
  93. /***************************************************************************
  94. *
  95. * @doc INTERNAL
  96. *
  97. * @func HRESULT FAR PASCAL | RcScanSziLeaf |
  98. * Scan a leaf node for a key and copy the associated data.
  99. *
  100. * @parm BK | bk |
  101. * the leaf block
  102. *
  103. * @parm KEY | key |
  104. * the key we're looking for
  105. *
  106. * @parm SHORT | wLevel |
  107. * the level of leaves (unnecessary)
  108. *
  109. * @parm QBTHR | qbthr |
  110. * the btree header
  111. *
  112. * @parm QV | qRec |
  113. * if found, record gets copied into this buffer
  114. *
  115. * @parm QTPOS | qbtpos |
  116. * pos of first key >= key goes here
  117. *
  118. * @rdesc ERR_SUCCESS if found; ERR_NOTEXIST if not found
  119. * If we are scanning for a key greater than any key in this
  120. * block, the pos returned will be invalid and will point just
  121. * past the last valid key in this block.
  122. *
  123. ***************************************************************************/
  124. PUBLIC HRESULT FAR PASCAL RcScanSziLeaf( BK bk, KEY key, SHORT wLevel,
  125. QBTHR qbthr, QV qRec, QBTPOS qbtpos)
  126. {
  127. QCB qcb;
  128. SZ sz;
  129. SHORT w, cKey;
  130. QB qb;
  131. HRESULT rc;
  132. HRESULT errb;
  133. LPB lpLigatureTable;
  134. if ((qcb = QFromBk(bk, wLevel, qbthr, &errb)) == NULL) {
  135. return errb;
  136. }
  137. rc = E_NOTEXIST;
  138. sz = qcb->db.rgbBlock + 2 * sizeof(BK);
  139. lpLigatureTable = (LPB)(((LPCHARTAB)*qbthr->lrglpCharTab)->lpLigature);
  140. for (cKey = 0; cKey < qcb->db.cKeys; cKey++)
  141. {
  142. w = WCmpiSz((SZ)key, sz, lpLigatureTable);
  143. if (w > 0) /* still looking for key */
  144. {
  145. sz += STRLEN(sz) + 1;
  146. sz += CbSizeRec(sz, qbthr);
  147. }
  148. else if (w < 0) /* key not found */
  149. {
  150. break;
  151. }
  152. else /* matched the key */
  153. {
  154. if (qRec != NULL)
  155. {
  156. qb = (QB)sz + STRLEN(sz) + 1;
  157. QVCOPY(qRec, qb, (LONG)CbSizeRec(qb, qbthr));
  158. }
  159. rc = S_OK;
  160. break;
  161. }
  162. }
  163. if (qbtpos != NULL)
  164. {
  165. qbtpos->bk = bk;
  166. qbtpos->cKey = cKey;
  167. qbtpos->iKey = (int)((QB)sz - (QB)qcb->db.rgbBlock);
  168. }
  169. return rc;
  170. }
  171. /* EOF */