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.

230 lines
5.9 KiB

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