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.

186 lines
4.8 KiB

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