Windows NT 4.0 source code leak
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.

410 lines
11 KiB

4 years ago
  1. /*****************************************************************************
  2. * *
  3. * BTKEY.C *
  4. * *
  5. * Copyright (C) Microsoft Corporation 1989, 1990. *
  6. * All Rights reserved. *
  7. * *
  8. ******************************************************************************
  9. * *
  10. * Module Intent *
  11. * *
  12. * Functions to deal with (i.e. size, compare) keys of all types. *
  13. * *
  14. ******************************************************************************
  15. * *
  16. * Testing Notes *
  17. * *
  18. ******************************************************************************
  19. * *
  20. * Current Owner: JohnSc *
  21. * *
  22. ******************************************************************************
  23. * *
  24. * Released by Development: long, long ago *
  25. * *
  26. *****************************************************************************/
  27. /*****************************************************************************
  28. *
  29. * Revision History: Created 05/11/89 by JohnSc
  30. *
  31. * 08/21/90 JohnSc autodocified
  32. *
  33. *****************************************************************************/
  34. #include <windows.h>
  35. #include <orkin.h>
  36. #include <string.h>
  37. #include "_mvfs.h"
  38. #include "imvfs.h"
  39. #include "btpriv.h"
  40. // _subsystem( btree );
  41. /*****************************************************************************
  42. * *
  43. * Macros *
  44. * *
  45. *****************************************************************************/
  46. #define StCopy(st1, st2) (ST)QvCopy( (st1), (st2), (LONG)*(st2) )
  47. #define CbLenSt(st) ((WORD)*(st))
  48. #if 0
  49. // Commented out because it's not used. Will need thought about compression.
  50. /***************************************************************************\
  51. *
  52. - Function: RcGetKey( pq, keyOld, pKey, kt )
  53. -
  54. * Status: API needs work
  55. *
  56. * Purpose: Copy a key, taking into account the previous key.
  57. *
  58. * ASSUMES
  59. *
  60. * args IN: pq - find the key here
  61. * keyOld - the old key to use
  62. * kt - key type
  63. *
  64. * PROMISES
  65. *
  66. * returns:
  67. * args OUT: pq - now points past end of key gotten
  68. * pKey - destination buffer key is expanded into
  69. *
  70. * Notes: It's not clear we want this function.
  71. * We probably don't need to copy stuff around this much.
  72. *
  73. \***************************************************************************/
  74. _hidden RC
  75. RcGetKey( pq, keyOld, pKey, kt )
  76. QV *pq;
  77. KEY keyOld, *pKey;
  78. KT kt;
  79. {
  80. BYTE cbSave;
  81. switch ( kt )
  82. {
  83. case KT_SZ:
  84. case KT_SZMIN:
  85. case KT_SZI:
  86. lstrcpy( (SZ)*pKey, (SZ)*pq );
  87. *(QB)pq += lstrlen( (SZ)*pq );
  88. break;
  89. case KT_LONG:
  90. // *pKey = *((KEY *)(*pq))++;
  91. // *(LONG FAR *)(*pKey) = *( oh fuck it.
  92. break;
  93. case KT_SZDEL:
  94. case KT_SZDELMIN:
  95. cbSave = **(QB *)pq;
  96. QvCopy( (QV)*pKey, (QV)keyOld, cbSave );
  97. lstrcpy( (SZ)*pKey + cbSave, *(SZ *)pq + 1 );
  98. *(QB *)pq += 1 + lstrlen( *(SZ *)pq + 1 );
  99. break;
  100. case KT_ST:
  101. case KT_STMIN:
  102. StCopy( (ST)*pKey, (ST)*pq );
  103. *(QB *)pq += 1 + CbLenSt( *(ST *)pq + 1 );
  104. break;
  105. case KT_STDEL:
  106. case KT_STDELMIN:
  107. cbSave = **(QB *)pq;
  108. QvCopy( (QV)*pKey, (QV)keyOld, cbSave );
  109. StCopy( (ST)*pKey + cbSave, *(ST *)pq + 1 );
  110. *(QB)pq += 1 + CbLenSt( (ST)pKey + 1 );
  111. break;
  112. default:
  113. return rcUnimplemented;
  114. break;
  115. }
  116. return rcSuccess;
  117. }
  118. #endif
  119. /***************************************************************************\
  120. *
  121. - Function: WCmpKey( key1, key2, qbthr )
  122. -
  123. * Purpose: Compare two keys.
  124. *
  125. * ASSUMES
  126. * args IN: key1, key2 - the UNCOMPRESSED keys to compare
  127. * qbthr->bth.rgchFormat[0] - key type
  128. * [qbthr->??? - other info ???]
  129. * state IN: [may someday use state if comparing compressed keys]
  130. *
  131. * PROMISES
  132. * returns: -1 if key1 < key2; 0 if key1 == key2; 1 if key1 > key2
  133. * args OUT: [if comparing compressed keys, change state in qbthr->???]
  134. * state OUT:
  135. *
  136. * Notes: Might be best to have this routine assume keys are expanded
  137. * and do something else to compare keys in the scan routines.
  138. * We're assuming fixed length keys are SZs. Alternative
  139. * would be to use a memcmp() function.
  140. *
  141. \***************************************************************************/
  142. _private INT
  143. WCmpKey( key1, key2, qbthr)
  144. KEY key1, key2;
  145. QBTHR qbthr;
  146. {
  147. INT w;
  148. KT kt = (KT)qbthr->bth.rgchFormat[ 0 ];
  149. LONG l1, l2;
  150. switch ( kt )
  151. {
  152. case KT_SZDEL: // assume keys have been expanded for delta codeds
  153. case KT_SZDELMIN:
  154. case KT_SZ:
  155. case KT_SZMIN:
  156. case '1': case '2': case '3': case '4': case '5': // assume null term
  157. case '6': case '7': case '8': case '9': case 'a':
  158. case 'b': case 'c': case 'd': case 'e': case 'f':
  159. w = strcmp( (SZ)key1, (SZ)key2 );
  160. break;
  161. case KT_SZI:
  162. w = WCmpiSz( (SZ)key1, (SZ)key2, qbthr->qbLigatures );
  163. break;
  164. case KT_SZISCAND:
  165. w = WCmpiScandSz( (SZ)key1, (SZ)key2 );
  166. break;
  167. case KT_ST:
  168. case KT_STMIN:
  169. case KT_STDEL:
  170. case KT_STDELMIN:
  171. w = WCmpSt( (ST)key1, (ST)key2 );
  172. break;
  173. case KT_LONG:
  174. l1 = *(LONG FAR *)key1;
  175. l2 = *(LONG FAR *)key2;
  176. if ( l1 < l2 )
  177. w = -1;
  178. else if ( l2 < l1 )
  179. w = 1;
  180. else
  181. w = 0;
  182. break;
  183. }
  184. return w;
  185. }
  186. /***************************************************************************\
  187. *
  188. - Function: CbSizeKey( key, qbthr, fCompressed )
  189. -
  190. * Purpose: Return the key size (compressed or un-) in bytes
  191. *
  192. * ASSUMES
  193. * args IN: key
  194. * qbthr
  195. * fCompressed - TRUE to get the compressed size,
  196. * FALSE to get the uncompressed size.
  197. *
  198. * PROMISES
  199. * returns: size of the key in bytes
  200. *
  201. * Note: It's impossible to tell how much suffix was discarded for
  202. * the KT_*MIN key types.
  203. *
  204. \***************************************************************************/
  205. _private INT
  206. CbSizeKey( key, qbthr, fCompressed )
  207. KEY key;
  208. QBTHR qbthr;
  209. BOOL fCompressed;
  210. {
  211. INT cb;
  212. KT kt = (KT)qbthr->bth.rgchFormat[ 0 ];
  213. switch( kt )
  214. {
  215. case KT_SZMIN:
  216. case KT_SZ:
  217. case KT_SZI:
  218. case KT_SZISCAND:
  219. cb = lstrlen( (SZ)key ) + 1;
  220. break;
  221. case KT_SZDEL:
  222. case KT_SZDELMIN:
  223. if ( fCompressed )
  224. {
  225. cb = 1 + lstrlen( (SZ)key + 1 ) + 1;
  226. }
  227. else
  228. {
  229. cb = *(QB)key + lstrlen( (SZ)key + 1 ) + 1;
  230. }
  231. break;
  232. case KT_ST:
  233. case KT_STMIN:
  234. case KT_STI:
  235. cb = CbLenSt( (ST)key ) + 1/* ? */;
  236. break;
  237. case KT_STDEL:
  238. case KT_STDELMIN:
  239. if ( fCompressed )
  240. {
  241. cb = 1 + CbLenSt( (ST)key + 1 );
  242. }
  243. else
  244. {
  245. cb = *(QB)key + CbLenSt( (ST)key + 1 ) + 1;
  246. }
  247. break;
  248. case KT_LONG:
  249. cb = sizeof( LONG );
  250. break;
  251. case '1': case '2': case '3': case '4': case '5':
  252. case '6': case '7': case '8': case '9':
  253. cb = kt - '0';
  254. break;
  255. case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
  256. cb = kt - 'a' + 10;
  257. break;
  258. }
  259. return cb;
  260. }
  261. /***************************************************************************\
  262. *
  263. - Function: FIsPrefix( hbt, key1, key2 )
  264. -
  265. * Purpose: Determines whether string key1 is a prefix of key2.
  266. *
  267. * ASSUMES
  268. * args IN: hbt - handle to a btree with string keys
  269. * key1, key2 - not compressed
  270. * state IN:
  271. *
  272. * PROMISES
  273. * returns: TRUE if the string key1 is a prefix of the string key2
  274. * FALSE if it isn't or if hbt doesn't contain string keys
  275. * globals OUT: rcBtreeError
  276. *
  277. * Bugs: Doesn't work on STs yet
  278. * +++
  279. *
  280. * Method: temporarily shortens the second string so it can
  281. * compare prefixes
  282. *
  283. \***************************************************************************/
  284. _public BOOL FAR PASCAL
  285. FIsPrefix( hbt, key1, key2)
  286. HBT hbt;
  287. KEY key1, key2;
  288. {
  289. QBTHR qbthr;
  290. INT cb1, cb2;
  291. CHAR c;
  292. KT kt;
  293. BOOL f;
  294. assert( hbt != NULL );
  295. qbthr = QLockGh( hbt );
  296. assert( qbthr != NULL );
  297. kt = (KT)qbthr->bth.rgchFormat[ 0 ];
  298. switch( kt )
  299. {
  300. case KT_SZMIN:
  301. case KT_SZ:
  302. case KT_SZI:
  303. case KT_SZISCAND:
  304. case KT_SZDEL:
  305. case KT_SZDELMIN:
  306. /* both keys assumed to have been decompressed */
  307. cb1 = lstrlen( (SZ)key1 );
  308. cb2 = lstrlen( (SZ)key2 );
  309. SetBtreeErrorRc(rcSuccess);
  310. break;
  311. case KT_ST:
  312. case KT_STMIN:
  313. case KT_STI:
  314. case KT_STDEL:
  315. case KT_STDELMIN:
  316. /* STs unimplemented */
  317. SetBtreeErrorRc(rcUnimplemented);
  318. UnlockGh( hbt );
  319. return FALSE;
  320. break;
  321. case KT_LONG:
  322. case '1': case '2': case '3': case '4': case '5':
  323. case '6': case '7': case '8': case '9':
  324. case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
  325. default:
  326. /* prefix doesn't make sense */
  327. SetBtreeErrorRc(rcInvalid);
  328. UnlockGh( hbt );
  329. return FALSE;
  330. break;
  331. }
  332. if ( cb1 > cb2 )
  333. {
  334. UnlockGh( hbt );
  335. return FALSE;
  336. }
  337. c = ((SZ)key2)[ cb1 ];
  338. ((SZ)key2)[ cb1 ] = '\0';
  339. switch ( kt )
  340. {
  341. case KT_SZMIN:
  342. case KT_SZ:
  343. case KT_SZDEL:
  344. case KT_SZDELMIN:
  345. f = !strcmp( (SZ)key1, (SZ)key2 );
  346. break;
  347. case KT_SZI:
  348. f = !WCmpiSz( (SZ)key1, (SZ)key2, qbthr->qbLigatures );
  349. break;
  350. case KT_SZISCAND:
  351. f = !WCmpiScandSz( (SZ)key1, (SZ)key2 );
  352. break;
  353. default:
  354. assert(FALSE);
  355. break;
  356. }
  357. ((SZ)key2)[ cb1 ] = c;
  358. UnlockGh( hbt );
  359. return f;
  360. }
  361. /* EOF */