mach0data.ic
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:16k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /**********************************************************************
  2. Utilities for converting data from the database file
  3. to the machine format. 
  4. (c) 1995 Innobase Oy
  5. Created 11/28/1995 Heikki Tuuri
  6. ***********************************************************************/
  7. /***********************************************************
  8. The following function is used to store data in one byte. */
  9. UNIV_INLINE
  10. void 
  11. mach_write_to_1(
  12. /*============*/
  13. byte*   b,      /* in: pointer to byte where to store */
  14. ulint   n)      /* in: ulint integer to be stored, >= 0, < 256 */ 
  15. {
  16. ut_ad(b);
  17. ut_ad(n <= 0xFF);
  18. b[0] = (byte)n;
  19. }
  20. /************************************************************
  21. The following function is used to fetch data from one byte. */
  22. UNIV_INLINE
  23. ulint 
  24. mach_read_from_1(
  25. /*=============*/
  26. /* out: ulint integer, >= 0, < 256 */
  27. byte*   b)      /* in: pointer to byte */
  28. {
  29. ut_ad(b);
  30. return((ulint)(b[0]));
  31. }
  32. /***********************************************************
  33. The following function is used to store data in two consecutive
  34. bytes. We store the most significant byte to the lowest address. */
  35. UNIV_INLINE
  36. void 
  37. mach_write_to_2(
  38. /*============*/
  39. byte*   b,      /* in: pointer to two bytes where to store */
  40. ulint n)      /* in: ulint integer to be stored */ 
  41. {
  42. ut_ad(b);
  43. ut_ad(n <= 0xFFFF);
  44. b[0] = (byte)(n >> 8);
  45. b[1] = (byte)(n);
  46. }
  47. /************************************************************
  48. The following function is used to fetch data from 2 consecutive
  49. bytes. The most significant byte is at the lowest address. */
  50. UNIV_INLINE
  51. ulint 
  52. mach_read_from_2(
  53. /*=============*/
  54. /* out: ulint integer */
  55. byte*   b)      /* in: pointer to 2 bytes */
  56. {
  57. ut_ad(b);
  58. return( ((ulint)(b[0]) << 8)
  59. + (ulint)(b[1])
  60.       );
  61. }
  62. /***********************************************************
  63. The following function is used to store data in 3 consecutive
  64. bytes. We store the most significant byte to the lowest address. */
  65. UNIV_INLINE
  66. void 
  67. mach_write_to_3(
  68. /*============*/
  69. byte*   b,      /* in: pointer to 3 bytes where to store */
  70. ulint n)      /* in: ulint integer to be stored */ 
  71. {
  72. ut_ad(b);
  73. ut_ad(n <= 0xFFFFFF);
  74. b[0] = (byte)(n >> 16);
  75. b[1] = (byte)(n >> 8);
  76. b[2] = (byte)(n);
  77. }
  78. /************************************************************
  79. The following function is used to fetch data from 3 consecutive
  80. bytes. The most significant byte is at the lowest address. */
  81. UNIV_INLINE
  82. ulint 
  83. mach_read_from_3(
  84. /*=============*/
  85. /* out: ulint integer */
  86. byte*   b)      /* in: pointer to 3 bytes */
  87. {
  88. ut_ad(b);
  89. return( ((ulint)(b[0]) << 16)
  90. + ((ulint)(b[1]) << 8)
  91. + (ulint)(b[2])
  92.       );
  93. }
  94. /***********************************************************
  95. The following function is used to store data in four consecutive
  96. bytes. We store the most significant byte to the lowest address. */
  97. UNIV_INLINE
  98. void 
  99. mach_write_to_4(
  100. /*============*/
  101. byte*   b,      /* in: pointer to four bytes where to store */
  102. ulint n)      /* in: ulint integer to be stored */ 
  103. {
  104. ut_ad(b);
  105. #if notdefined && !defined(__STDC__) && defined(UNIV_INTEL) && (UNIV_WORD_SIZE == 4) && defined(UNIV_VISUALC)
  106. /* We do not use this even on Intel, because unaligned accesses may
  107. be slow */
  108. __asm MOV EAX, n
  109. __asm BSWAP EAX /* Intel is little-endian, must swap bytes */
  110. __asm MOV n, EAX
  111. *((ulint*)b) = n;
  112. #else
  113. b[0] = (byte)(n >> 24);
  114. b[1] = (byte)(n >> 16);
  115. b[2] = (byte)(n >> 8);
  116. b[3] = (byte)n;
  117. #endif
  118. }
  119. /************************************************************
  120. The following function is used to fetch data from 4 consecutive
  121. bytes. The most significant byte is at the lowest address. */
  122. UNIV_INLINE
  123. ulint 
  124. mach_read_from_4(
  125. /*=============*/
  126. /* out: ulint integer */
  127. byte*   b)      /* in: pointer to four bytes */
  128. {
  129. #if notdefined && !defined(__STDC__) && defined(UNIV_INTEL) && (UNIV_WORD_SIZE == 4) && defined(UNIV_VISUALC)
  130. /* We do not use this even on Intel, because unaligned accesses may
  131. be slow */
  132. ulint res;
  133. ut_ad(b);
  134. __asm MOV EDX, b
  135. __asm MOV ECX, DWORD PTR [EDX]
  136. __asm BSWAP ECX /* Intel is little-endian, must swap bytes */
  137. __asm MOV res, ECX
  138. return(res);
  139. #else
  140. ut_ad(b);
  141. return( ((ulint)(b[0]) << 24)
  142. + ((ulint)(b[1]) << 16)
  143. + ((ulint)(b[2]) << 8)
  144. + (ulint)(b[3])
  145.       );
  146. #endif
  147. }
  148. /***********************************************************
  149. The following function is used to store data from a ulint to memory
  150. in standard order: we store the most significant byte to the lowest
  151. address. */
  152. UNIV_INLINE
  153. void 
  154. mach_write(
  155. /*=======*/
  156. byte*   b,      /* in: pointer to 4 bytes where to store */
  157. ulint   n)      /* in: ulint integer to be stored */ 
  158. {
  159. ut_ad(b);
  160. b[0] = (byte)(n >> 24);
  161. b[1] = (byte)(n >> 16);
  162. b[2] = (byte)(n >> 8);
  163. b[3] = (byte)n;
  164. }
  165. /************************************************************
  166. The following function is used to fetch data from memory to a ulint.
  167. The most significant byte is at the lowest address. */
  168. UNIV_INLINE
  169. ulint 
  170. mach_read(
  171. /*======*/
  172. /* out: ulint integer */
  173. byte*   b)      /* in: pointer to 4 bytes */
  174. {
  175. ut_ad(b);
  176. return( ((ulint)(b[0]) << 24)
  177. + ((ulint)(b[1]) << 16)
  178. + ((ulint)(b[2]) << 8)
  179. + (ulint)(b[3])
  180.       );
  181. }
  182. /*************************************************************
  183. Writes a ulint in a compressed form where the first byte codes the
  184. length of the stored ulint. We look at the most significant bits of
  185. the byte. If the most significant bit is zero, it means 1-byte storage,
  186. else if the 2nd bit is 0, it means 2-byte storage, else if 3rd is 0,
  187. it means 3-byte storage, else if 4th is 0, it means 4-byte storage, 
  188. else the storage is 5-byte. */
  189. UNIV_INLINE
  190. ulint
  191. mach_write_compressed(
  192. /*==================*/
  193. /* out: compressed size in bytes */
  194. byte*   b,      /* in: pointer to memory where to store */
  195. ulint   n)      /* in: ulint integer (< 2^32) to be stored */ 
  196. {
  197. ut_ad(b);
  198. if (n < 0x80) {
  199. mach_write_to_1(b, n);
  200. return(1);
  201. } else if (n < 0x4000) {
  202. mach_write_to_2(b, n | 0x8000);
  203. return(2);
  204. } else if (n < 0x200000) {
  205. mach_write_to_3(b, n | 0xC00000);
  206. return(3);
  207. } else if (n < 0x10000000) {
  208. mach_write_to_4(b, n | 0xE0000000);
  209. return(4);
  210. } else {
  211. mach_write_to_1(b, 0xF0);
  212. mach_write_to_4(b + 1, n);
  213. return(5);
  214. }
  215. }
  216. /*************************************************************
  217. Returns the size of a ulint when written in the compressed form. */
  218. UNIV_INLINE
  219. ulint
  220. mach_get_compressed_size(
  221. /*=====================*/
  222. /* out: compressed size in bytes */
  223. ulint   n)      /* in: ulint integer (< 2^32) to be stored */ 
  224. {
  225. if (n < 0x80) {
  226. return(1);
  227. } else if (n < 0x4000) {
  228. return(2);
  229. } else if (n < 0x200000) {
  230. return(3);
  231. } else if (n < 0x10000000) {
  232. return(4);
  233. } else {
  234. return(5);
  235. }
  236. }
  237. /*************************************************************
  238. Reads a ulint in a compressed form. */
  239. UNIV_INLINE
  240. ulint
  241. mach_read_compressed(
  242. /*=================*/
  243. /* out: read integer (< 2^32) */
  244. byte*   b)      /* in: pointer to memory from where to read */
  245. {
  246. ulint flag;
  247. ut_ad(b);
  248. flag = mach_read_from_1(b);
  249. if (flag < 0x80) {
  250. return(flag);
  251. } else if (flag < 0xC0) {
  252. return(mach_read_from_2(b) & 0x7FFF);
  253. } else if (flag < 0xE0) {
  254. return(mach_read_from_3(b) & 0x3FFFFF);
  255. } else if (flag < 0xF0) {
  256. return(mach_read_from_4(b) & 0x1FFFFFFF);
  257. } else {
  258. ut_ad(flag == 0xF0);
  259. return(mach_read_from_4(b + 1));
  260. }
  261. }
  262. /***********************************************************
  263. The following function is used to store data in 8 consecutive
  264. bytes. We store the most significant byte to the lowest address. */
  265. UNIV_INLINE
  266. void 
  267. mach_write_to_8(
  268. /*============*/
  269. byte*   b,      /* in: pointer to 8 bytes where to store */
  270. dulint n)      /* in: dulint integer to be stored */ 
  271. {
  272. ut_ad(b);
  273. mach_write_to_4(b, ut_dulint_get_high(n));
  274. mach_write_to_4(b + 4, ut_dulint_get_low(n));
  275. }
  276. /************************************************************
  277. The following function is used to fetch data from 8 consecutive
  278. bytes. The most significant byte is at the lowest address. */
  279. UNIV_INLINE
  280. dulint 
  281. mach_read_from_8(
  282. /*=============*/
  283. /* out: dulint integer */
  284. byte*   b)      /* in: pointer to 8 bytes */
  285. {
  286. ulint high;
  287. ulint low;
  288. ut_ad(b);
  289. high = mach_read_from_4(b);
  290. low = mach_read_from_4(b + 4);
  291. return(ut_dulint_create(high, low)); 
  292. }
  293. /***********************************************************
  294. The following function is used to store data in 7 consecutive
  295. bytes. We store the most significant byte to the lowest address. */
  296. UNIV_INLINE
  297. void 
  298. mach_write_to_7(
  299. /*============*/
  300. byte*   b,      /* in: pointer to 7 bytes where to store */
  301. dulint n)      /* in: dulint integer to be stored */ 
  302. {
  303. ut_ad(b);
  304. mach_write_to_3(b, ut_dulint_get_high(n));
  305. mach_write_to_4(b + 3, ut_dulint_get_low(n));
  306. }
  307. /************************************************************
  308. The following function is used to fetch data from 7 consecutive
  309. bytes. The most significant byte is at the lowest address. */
  310. UNIV_INLINE
  311. dulint 
  312. mach_read_from_7(
  313. /*=============*/
  314. /* out: dulint integer */
  315. byte*   b)      /* in: pointer to 7 bytes */
  316. {
  317. ulint high;
  318. ulint low;
  319. ut_ad(b);
  320. high = mach_read_from_3(b);
  321. low = mach_read_from_4(b + 3);
  322. return(ut_dulint_create(high, low)); 
  323. }
  324. /***********************************************************
  325. The following function is used to store data in 6 consecutive
  326. bytes. We store the most significant byte to the lowest address. */
  327. UNIV_INLINE
  328. void 
  329. mach_write_to_6(
  330. /*============*/
  331. byte*   b,      /* in: pointer to 6 bytes where to store */
  332. dulint n)      /* in: dulint integer to be stored */ 
  333. {
  334. ut_ad(b);
  335. mach_write_to_2(b, ut_dulint_get_high(n));
  336. mach_write_to_4(b + 2, ut_dulint_get_low(n));
  337. }
  338. /************************************************************
  339. The following function is used to fetch data from 6 consecutive
  340. bytes. The most significant byte is at the lowest address. */
  341. UNIV_INLINE
  342. dulint 
  343. mach_read_from_6(
  344. /*=============*/
  345. /* out: dulint integer */
  346. byte*   b)      /* in: pointer to 7 bytes */
  347. {
  348. ulint high;
  349. ulint low;
  350. ut_ad(b);
  351. high = mach_read_from_2(b);
  352. low = mach_read_from_4(b + 2);
  353. return(ut_dulint_create(high, low)); 
  354. }
  355. /*************************************************************
  356. Writes a dulint in a compressed form. */
  357. UNIV_INLINE
  358. ulint
  359. mach_dulint_write_compressed(
  360. /*=========================*/
  361. /* out: size in bytes */
  362. byte*   b,      /* in: pointer to memory where to store */
  363. dulint  n)      /* in: dulint integer to be stored */ 
  364. {
  365. ulint size;
  366. ut_ad(b);
  367. size = mach_write_compressed(b, ut_dulint_get_high(n));
  368. mach_write_to_4(b + size, ut_dulint_get_low(n));
  369. return(size + 4);
  370. }
  371. /*************************************************************
  372. Returns the size of a dulint when written in the compressed form. */
  373. UNIV_INLINE
  374. ulint
  375. mach_dulint_get_compressed_size(
  376. /*============================*/
  377. /* out: compressed size in bytes */
  378. dulint   n)     /* in: dulint integer to be stored */ 
  379. {
  380. return(4 + mach_get_compressed_size(ut_dulint_get_high(n)));
  381. }
  382. /*************************************************************
  383. Reads a dulint in a compressed form. */
  384. UNIV_INLINE
  385. dulint
  386. mach_dulint_read_compressed(
  387. /*========================*/
  388. /* out: read dulint */
  389. byte*   b)      /* in: pointer to memory from where to read */
  390. {
  391. ulint high;
  392. ulint low;
  393. ulint size;
  394. ut_ad(b);
  395. high = mach_read_compressed(b);
  396. size = mach_get_compressed_size(high);
  397. low = mach_read_from_4(b + size);
  398. return(ut_dulint_create(high, low)); 
  399. }
  400. /*************************************************************
  401. Writes a dulint in a compressed form. */
  402. UNIV_INLINE
  403. ulint
  404. mach_dulint_write_much_compressed(
  405. /*==============================*/
  406. /* out: size in bytes */
  407. byte*   b,      /* in: pointer to memory where to store */
  408. dulint  n)      /* in: dulint integer to be stored */ 
  409. {
  410. ulint size;
  411. ut_ad(b);
  412. if (ut_dulint_get_high(n) == 0) {
  413. return(mach_write_compressed(b, ut_dulint_get_low(n)));
  414. }
  415. *b = 0xFF;
  416. size = 1 + mach_write_compressed(b + 1, ut_dulint_get_high(n));
  417. size += mach_write_compressed(b + size, ut_dulint_get_low(n));
  418. return(size);
  419. }
  420. /*************************************************************
  421. Returns the size of a dulint when written in the compressed form. */
  422. UNIV_INLINE
  423. ulint
  424. mach_dulint_get_much_compressed_size(
  425. /*=================================*/
  426. /* out: compressed size in bytes */
  427. dulint   n)     /* in: dulint integer to be stored */ 
  428. {
  429. if (0 == ut_dulint_get_high(n)) {
  430. return(mach_get_compressed_size(ut_dulint_get_low(n)));
  431. }
  432. return(1 + mach_get_compressed_size(ut_dulint_get_high(n))
  433.        + mach_get_compressed_size(ut_dulint_get_low(n)));
  434. }
  435. /*************************************************************
  436. Reads a dulint in a compressed form. */
  437. UNIV_INLINE
  438. dulint
  439. mach_dulint_read_much_compressed(
  440. /*=============================*/
  441. /* out: read dulint */
  442. byte*   b)      /* in: pointer to memory from where to read */
  443. {
  444. ulint high;
  445. ulint low;
  446. ulint size;
  447. ut_ad(b);
  448. if (*b != 0xFF) {
  449. high = 0;
  450. size = 0;
  451. } else {
  452. high = mach_read_compressed(b + 1);
  453. size = 1 + mach_get_compressed_size(high);
  454. }
  455. low = mach_read_compressed(b + size);
  456. return(ut_dulint_create(high, low)); 
  457. }
  458. /*************************************************************
  459. Reads a double. It is stored in a little-endian format. */
  460. UNIV_INLINE
  461. double
  462. mach_double_read(
  463. /*=============*/
  464. /* out: double read */
  465. byte*   b)      /* in: pointer to memory from where to read */
  466. {
  467. double  d;
  468. ulint i;
  469. byte* ptr;
  470. ptr = (byte*)&d;
  471. for (i = 0; i < sizeof(double); i++) {
  472. #ifdef WORDS_BIGENDIAN
  473. ptr[sizeof(double) - i - 1] = b[i];
  474. #else
  475. ptr[i] = b[i];
  476. #endif
  477. }
  478. return(d);
  479. }
  480. /*************************************************************
  481. Writes a double. It is stored in a little-endian format. */
  482. UNIV_INLINE
  483. void
  484. mach_double_write(
  485. /*==============*/
  486. byte*   b,      /* in: pointer to memory where to write */
  487. double  d) /* in: double */
  488. {
  489. ulint i;
  490. byte* ptr;
  491. ptr = (byte*)&d;
  492. for (i = 0; i < sizeof(double); i++) {
  493. #ifdef WORDS_BIGENDIAN
  494. b[i] = ptr[sizeof(double) - i - 1];
  495. #else
  496. b[i] = ptr[i];
  497. #endif
  498. }
  499. }
  500. /*************************************************************
  501. Reads a float. It is stored in a little-endian format. */
  502. UNIV_INLINE
  503. float
  504. mach_float_read(
  505. /*=============*/
  506. /* out: float read */
  507. byte*   b)      /* in: pointer to memory from where to read */
  508. {
  509. float  d;
  510. ulint i;
  511. byte* ptr;
  512. ptr = (byte*)&d;
  513. for (i = 0; i < sizeof(float); i++) {
  514. #ifdef WORDS_BIGENDIAN
  515. ptr[sizeof(float) - i - 1] = b[i];
  516. #else
  517. ptr[i] = b[i];
  518. #endif
  519. }
  520. return(d);
  521. }
  522. /*************************************************************
  523. Writes a float. It is stored in a little-endian format. */
  524. UNIV_INLINE
  525. void
  526. mach_float_write(
  527. /*==============*/
  528. byte*   b,      /* in: pointer to memory where to write */
  529. float  d) /* in: float */
  530. {
  531. ulint i;
  532. byte* ptr;
  533. ptr = (byte*)&d;
  534. for (i = 0; i < sizeof(float); i++) {
  535. #ifdef WORDS_BIGENDIAN
  536. b[i] = ptr[sizeof(float) - i - 1];
  537. #else
  538. b[i] = ptr[i];
  539. #endif
  540. }
  541. }
  542. /*************************************************************
  543. Reads a ulint stored in the little-endian format. */
  544. UNIV_INLINE
  545. ulint
  546. mach_read_from_n_little_endian(
  547. /*===========================*/
  548. /* out: unsigned long int */
  549. byte* buf, /* in: from where to read */
  550. ulint buf_size) /* in: from how many bytes to read */
  551. {
  552. ulint n = 0;
  553. byte* ptr;
  554. ut_ad(buf_size <= sizeof(ulint));
  555. ut_ad(buf_size > 0);
  556. ptr = buf + buf_size;
  557. for (;;) {
  558. ptr--;
  559. n = n << 8;
  560. n += (ulint)(*ptr);
  561. if (ptr == buf) {
  562. break;
  563. }
  564. }
  565. return(n);
  566. }
  567. /*************************************************************
  568. Writes a ulint in the little-endian format. */
  569. UNIV_INLINE
  570. void
  571. mach_write_to_n_little_endian(
  572. /*==========================*/
  573. byte* dest, /* in: where to write */
  574. ulint dest_size, /* in: into how many bytes to write */
  575. ulint n) /* in: unsigned long int to write */
  576. {
  577. byte* end;
  578. ut_ad(dest_size <= sizeof(ulint));
  579. ut_ad(dest_size > 0);
  580. end = dest + dest_size;
  581. for (;;) {
  582. *dest = (byte)(n & 0xFF);
  583. n = n >> 8;
  584. dest++;
  585. if (dest == end) {
  586. break;
  587. }
  588. ut_ad(n == 0);
  589. }
  590. /*************************************************************
  591. Reads a ulint stored in the little-endian format. */
  592. UNIV_INLINE
  593. ulint
  594. mach_read_from_2_little_endian(
  595. /*===========================*/
  596. /* out: unsigned long int */
  597. byte* buf) /* in: from where to read */
  598. {
  599. return((ulint)(*buf) + ((ulint)(*(buf + 1))) * 256);
  600. }
  601. /*************************************************************
  602. Writes a ulint in the little-endian format. */
  603. UNIV_INLINE
  604. void
  605. mach_write_to_2_little_endian(
  606. /*==========================*/
  607. byte* dest, /* in: where to write */
  608. ulint n) /* in: unsigned long int to write */
  609. {
  610. ut_ad(n < 256 * 256);
  611. *dest = (byte)(n & 0xFF);
  612. n = n >> 8;
  613. dest++;
  614. *dest = (byte)(n & 0xFF);
  615. }