mach0data.ic
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小: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 <= 0xFFUL);
  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 <= 0xFFFFUL);
  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 <= 0xFFFFFFUL);
  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 (0 == 1) && !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 (0 == 1) && !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. Writes a ulint in a compressed form where the first byte codes the
  150. length of the stored ulint. We look at the most significant bits of
  151. the byte. If the most significant bit is zero, it means 1-byte storage,
  152. else if the 2nd bit is 0, it means 2-byte storage, else if 3rd is 0,
  153. it means 3-byte storage, else if 4th is 0, it means 4-byte storage, 
  154. else the storage is 5-byte. */
  155. UNIV_INLINE
  156. ulint
  157. mach_write_compressed(
  158. /*==================*/
  159. /* out: compressed size in bytes */
  160. byte*   b,      /* in: pointer to memory where to store */
  161. ulint   n)      /* in: ulint integer (< 2^32) to be stored */ 
  162. {
  163. ut_ad(b);
  164. if (n < 0x80UL) {
  165. mach_write_to_1(b, n);
  166. return(1);
  167. } else if (n < 0x4000UL) {
  168. mach_write_to_2(b, n | 0x8000UL);
  169. return(2);
  170. } else if (n < 0x200000UL) {
  171. mach_write_to_3(b, n | 0xC00000UL);
  172. return(3);
  173. } else if (n < 0x10000000UL) {
  174. mach_write_to_4(b, n | 0xE0000000UL);
  175. return(4);
  176. } else {
  177. mach_write_to_1(b, 0xF0UL);
  178. mach_write_to_4(b + 1, n);
  179. return(5);
  180. }
  181. }
  182. /*************************************************************
  183. Returns the size of a ulint when written in the compressed form. */
  184. UNIV_INLINE
  185. ulint
  186. mach_get_compressed_size(
  187. /*=====================*/
  188. /* out: compressed size in bytes */
  189. ulint   n)      /* in: ulint integer (< 2^32) to be stored */ 
  190. {
  191. if (n < 0x80UL) {
  192. return(1);
  193. } else if (n < 0x4000UL) {
  194. return(2);
  195. } else if (n < 0x200000UL) {
  196. return(3);
  197. } else if (n < 0x10000000UL) {
  198. return(4);
  199. } else {
  200. return(5);
  201. }
  202. }
  203. /*************************************************************
  204. Reads a ulint in a compressed form. */
  205. UNIV_INLINE
  206. ulint
  207. mach_read_compressed(
  208. /*=================*/
  209. /* out: read integer (< 2^32) */
  210. byte*   b)      /* in: pointer to memory from where to read */
  211. {
  212. ulint flag;
  213. ut_ad(b);
  214. flag = mach_read_from_1(b);
  215. if (flag < 0x80UL) {
  216. return(flag);
  217. } else if (flag < 0xC0UL) {
  218. return(mach_read_from_2(b) & 0x7FFFUL);
  219. } else if (flag < 0xE0UL) {
  220. return(mach_read_from_3(b) & 0x3FFFFFUL);
  221. } else if (flag < 0xF0UL) {
  222. return(mach_read_from_4(b) & 0x1FFFFFFFUL);
  223. } else {
  224. ut_ad(flag == 0xF0UL);
  225. return(mach_read_from_4(b + 1));
  226. }
  227. }
  228. /***********************************************************
  229. The following function is used to store data in 8 consecutive
  230. bytes. We store the most significant byte to the lowest address. */
  231. UNIV_INLINE
  232. void 
  233. mach_write_to_8(
  234. /*============*/
  235. byte*   b,      /* in: pointer to 8 bytes where to store */
  236. dulint n)      /* in: dulint integer to be stored */ 
  237. {
  238. ut_ad(b);
  239. mach_write_to_4(b, ut_dulint_get_high(n));
  240. mach_write_to_4(b + 4, ut_dulint_get_low(n));
  241. }
  242. /************************************************************
  243. The following function is used to fetch data from 8 consecutive
  244. bytes. The most significant byte is at the lowest address. */
  245. UNIV_INLINE
  246. dulint 
  247. mach_read_from_8(
  248. /*=============*/
  249. /* out: dulint integer */
  250. byte*   b)      /* in: pointer to 8 bytes */
  251. {
  252. ulint high;
  253. ulint low;
  254. ut_ad(b);
  255. high = mach_read_from_4(b);
  256. low = mach_read_from_4(b + 4);
  257. return(ut_dulint_create(high, low)); 
  258. }
  259. /***********************************************************
  260. The following function is used to store data in 7 consecutive
  261. bytes. We store the most significant byte to the lowest address. */
  262. UNIV_INLINE
  263. void 
  264. mach_write_to_7(
  265. /*============*/
  266. byte*   b,      /* in: pointer to 7 bytes where to store */
  267. dulint n)      /* in: dulint integer to be stored */ 
  268. {
  269. ut_ad(b);
  270. mach_write_to_3(b, ut_dulint_get_high(n));
  271. mach_write_to_4(b + 3, ut_dulint_get_low(n));
  272. }
  273. /************************************************************
  274. The following function is used to fetch data from 7 consecutive
  275. bytes. The most significant byte is at the lowest address. */
  276. UNIV_INLINE
  277. dulint 
  278. mach_read_from_7(
  279. /*=============*/
  280. /* out: dulint integer */
  281. byte*   b)      /* in: pointer to 7 bytes */
  282. {
  283. ulint high;
  284. ulint low;
  285. ut_ad(b);
  286. high = mach_read_from_3(b);
  287. low = mach_read_from_4(b + 3);
  288. return(ut_dulint_create(high, low)); 
  289. }
  290. /***********************************************************
  291. The following function is used to store data in 6 consecutive
  292. bytes. We store the most significant byte to the lowest address. */
  293. UNIV_INLINE
  294. void 
  295. mach_write_to_6(
  296. /*============*/
  297. byte*   b,      /* in: pointer to 6 bytes where to store */
  298. dulint n)      /* in: dulint integer to be stored */ 
  299. {
  300. ut_ad(b);
  301. mach_write_to_2(b, ut_dulint_get_high(n));
  302. mach_write_to_4(b + 2, ut_dulint_get_low(n));
  303. }
  304. /************************************************************
  305. The following function is used to fetch data from 6 consecutive
  306. bytes. The most significant byte is at the lowest address. */
  307. UNIV_INLINE
  308. dulint 
  309. mach_read_from_6(
  310. /*=============*/
  311. /* out: dulint integer */
  312. byte*   b)      /* in: pointer to 7 bytes */
  313. {
  314. ulint high;
  315. ulint low;
  316. ut_ad(b);
  317. high = mach_read_from_2(b);
  318. low = mach_read_from_4(b + 2);
  319. return(ut_dulint_create(high, low)); 
  320. }
  321. /*************************************************************
  322. Writes a dulint in a compressed form (5..9 bytes). */
  323. UNIV_INLINE
  324. ulint
  325. mach_dulint_write_compressed(
  326. /*=========================*/
  327. /* out: size in bytes */
  328. byte*   b,      /* in: pointer to memory where to store */
  329. dulint  n)      /* in: dulint integer to be stored */ 
  330. {
  331. ulint size;
  332. ut_ad(b);
  333. size = mach_write_compressed(b, ut_dulint_get_high(n));
  334. mach_write_to_4(b + size, ut_dulint_get_low(n));
  335. return(size + 4);
  336. }
  337. /*************************************************************
  338. Returns the size of a dulint when written in the compressed form. */
  339. UNIV_INLINE
  340. ulint
  341. mach_dulint_get_compressed_size(
  342. /*============================*/
  343. /* out: compressed size in bytes */
  344. dulint   n)     /* in: dulint integer to be stored */ 
  345. {
  346. return(4 + mach_get_compressed_size(ut_dulint_get_high(n)));
  347. }
  348. /*************************************************************
  349. Reads a dulint in a compressed form. */
  350. UNIV_INLINE
  351. dulint
  352. mach_dulint_read_compressed(
  353. /*========================*/
  354. /* out: read dulint */
  355. byte*   b)      /* in: pointer to memory from where to read */
  356. {
  357. ulint high;
  358. ulint low;
  359. ulint size;
  360. ut_ad(b);
  361. high = mach_read_compressed(b);
  362. size = mach_get_compressed_size(high);
  363. low = mach_read_from_4(b + size);
  364. return(ut_dulint_create(high, low)); 
  365. }
  366. /*************************************************************
  367. Writes a dulint in a compressed form (1..11 bytes). */
  368. UNIV_INLINE
  369. ulint
  370. mach_dulint_write_much_compressed(
  371. /*==============================*/
  372. /* out: size in bytes */
  373. byte*   b,      /* in: pointer to memory where to store */
  374. dulint  n)      /* in: dulint integer to be stored */ 
  375. {
  376. ulint size;
  377. ut_ad(b);
  378. if (ut_dulint_get_high(n) == 0) {
  379. return(mach_write_compressed(b, ut_dulint_get_low(n)));
  380. }
  381. *b = (byte)0xFF;
  382. size = 1 + mach_write_compressed(b + 1, ut_dulint_get_high(n));
  383. size += mach_write_compressed(b + size, ut_dulint_get_low(n));
  384. return(size);
  385. }
  386. /*************************************************************
  387. Returns the size of a dulint when written in the compressed form. */
  388. UNIV_INLINE
  389. ulint
  390. mach_dulint_get_much_compressed_size(
  391. /*=================================*/
  392. /* out: compressed size in bytes */
  393. dulint   n)     /* in: dulint integer to be stored */ 
  394. {
  395. if (0 == ut_dulint_get_high(n)) {
  396. return(mach_get_compressed_size(ut_dulint_get_low(n)));
  397. }
  398. return(1 + mach_get_compressed_size(ut_dulint_get_high(n))
  399.        + mach_get_compressed_size(ut_dulint_get_low(n)));
  400. }
  401. /*************************************************************
  402. Reads a dulint in a compressed form. */
  403. UNIV_INLINE
  404. dulint
  405. mach_dulint_read_much_compressed(
  406. /*=============================*/
  407. /* out: read dulint */
  408. byte*   b)      /* in: pointer to memory from where to read */
  409. {
  410. ulint high;
  411. ulint low;
  412. ulint size;
  413. ut_ad(b);
  414. if (*b != (byte)0xFF) {
  415. high = 0;
  416. size = 0;
  417. } else {
  418. high = mach_read_compressed(b + 1);
  419. size = 1 + mach_get_compressed_size(high);
  420. }
  421. low = mach_read_compressed(b + size);
  422. return(ut_dulint_create(high, low)); 
  423. }
  424. /*************************************************************
  425. Reads a double. It is stored in a little-endian format. */
  426. UNIV_INLINE
  427. double
  428. mach_double_read(
  429. /*=============*/
  430. /* out: double read */
  431. byte*   b)      /* in: pointer to memory from where to read */
  432. {
  433. double  d;
  434. ulint i;
  435. byte* ptr;
  436. ptr = (byte*)&d;
  437. for (i = 0; i < sizeof(double); i++) {
  438. #ifdef WORDS_BIGENDIAN
  439. ptr[sizeof(double) - i - 1] = b[i];
  440. #else
  441. ptr[i] = b[i];
  442. #endif
  443. }
  444. return(d);
  445. }
  446. /*************************************************************
  447. Writes a double. It is stored in a little-endian format. */
  448. UNIV_INLINE
  449. void
  450. mach_double_write(
  451. /*==============*/
  452. byte*   b,      /* in: pointer to memory where to write */
  453. double  d) /* in: double */
  454. {
  455. ulint i;
  456. byte* ptr;
  457. ptr = (byte*)&d;
  458. for (i = 0; i < sizeof(double); i++) {
  459. #ifdef WORDS_BIGENDIAN
  460. b[i] = ptr[sizeof(double) - i - 1];
  461. #else
  462. b[i] = ptr[i];
  463. #endif
  464. }
  465. }
  466. /*************************************************************
  467. Reads a float. It is stored in a little-endian format. */
  468. UNIV_INLINE
  469. float
  470. mach_float_read(
  471. /*=============*/
  472. /* out: float read */
  473. byte*   b)      /* in: pointer to memory from where to read */
  474. {
  475. float  d;
  476. ulint i;
  477. byte* ptr;
  478. ptr = (byte*)&d;
  479. for (i = 0; i < sizeof(float); i++) {
  480. #ifdef WORDS_BIGENDIAN
  481. ptr[sizeof(float) - i - 1] = b[i];
  482. #else
  483. ptr[i] = b[i];
  484. #endif
  485. }
  486. return(d);
  487. }
  488. /*************************************************************
  489. Writes a float. It is stored in a little-endian format. */
  490. UNIV_INLINE
  491. void
  492. mach_float_write(
  493. /*==============*/
  494. byte*   b,      /* in: pointer to memory where to write */
  495. float  d) /* in: float */
  496. {
  497. ulint i;
  498. byte* ptr;
  499. ptr = (byte*)&d;
  500. for (i = 0; i < sizeof(float); i++) {
  501. #ifdef WORDS_BIGENDIAN
  502. b[i] = ptr[sizeof(float) - i - 1];
  503. #else
  504. b[i] = ptr[i];
  505. #endif
  506. }
  507. }
  508. /*************************************************************
  509. Reads a ulint stored in the little-endian format. */
  510. UNIV_INLINE
  511. ulint
  512. mach_read_from_n_little_endian(
  513. /*===========================*/
  514. /* out: unsigned long int */
  515. byte* buf, /* in: from where to read */
  516. ulint buf_size) /* in: from how many bytes to read */
  517. {
  518. ulint n = 0;
  519. byte* ptr;
  520. ut_ad(buf_size <= sizeof(ulint));
  521. ut_ad(buf_size > 0);
  522. ptr = buf + buf_size;
  523. for (;;) {
  524. ptr--;
  525. n = n << 8;
  526. n += (ulint)(*ptr);
  527. if (ptr == buf) {
  528. break;
  529. }
  530. }
  531. return(n);
  532. }
  533. /*************************************************************
  534. Writes a ulint in the little-endian format. */
  535. UNIV_INLINE
  536. void
  537. mach_write_to_n_little_endian(
  538. /*==========================*/
  539. byte* dest, /* in: where to write */
  540. ulint dest_size, /* in: into how many bytes to write */
  541. ulint n) /* in: unsigned long int to write */
  542. {
  543. byte* end;
  544. ut_ad(dest_size <= sizeof(ulint));
  545. ut_ad(dest_size > 0);
  546. end = dest + dest_size;
  547. for (;;) {
  548. *dest = (byte)(n & 0xFF);
  549. n = n >> 8;
  550. dest++;
  551. if (dest == end) {
  552. break;
  553. }
  554. ut_ad(n == 0);
  555. }
  556. /*************************************************************
  557. Reads a ulint stored in the little-endian format. */
  558. UNIV_INLINE
  559. ulint
  560. mach_read_from_2_little_endian(
  561. /*===========================*/
  562. /* out: unsigned long int */
  563. byte* buf) /* in: from where to read */
  564. {
  565. return((ulint)(*buf) + ((ulint)(*(buf + 1))) * 256);
  566. }
  567. /*************************************************************
  568. Writes a ulint in the little-endian format. */
  569. UNIV_INLINE
  570. void
  571. mach_write_to_2_little_endian(
  572. /*==========================*/
  573. byte* dest, /* in: where to write */
  574. ulint n) /* in: unsigned long int to write */
  575. {
  576. ut_ad(n < 256 * 256);
  577. *dest = (byte)(n & 0xFFUL);
  578. n = n >> 8;
  579. dest++;
  580. *dest = (byte)(n & 0xFFUL);
  581. }