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.

881 lines
20 KiB

17 years ago
17 years ago
17 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
15 years ago
16 years ago
16 years ago
15 years ago
15 years ago
16 years ago
16 years ago
15 years ago
15 years ago
16 years ago
15 years ago
16 years ago
15 years ago
15 years ago
16 years ago
16 years ago
15 years ago
15 years ago
16 years ago
15 years ago
16 years ago
15 years ago
16 years ago
15 years ago
15 years ago
16 years ago
15 years ago
16 years ago
15 years ago
15 years ago
16 years ago
15 years ago
15 years ago
16 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
16 years ago
15 years ago
16 years ago
15 years ago
15 years ago
15 years ago
15 years ago
16 years ago
15 years ago
16 years ago
15 years ago
15 years ago
15 years ago
16 years ago
15 years ago
15 years ago
16 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
  1. /*****************************************************************************
  2. Copyright (c) 1995, 2009, Oracle and/or its affiliates. All Rights Reserved.
  3. This program is free software; you can redistribute it and/or modify it under
  4. the terms of the GNU General Public License as published by the Free Software
  5. Foundation; version 2 of the License.
  6. This program is distributed in the hope that it will be useful, but WITHOUT
  7. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along with
  10. this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
  12. *****************************************************************************/
  13. /******************************************************************//**
  14. @file include/mach0data.ic
  15. Utilities for converting data from the database file
  16. to the machine format.
  17. Created 11/28/1995 Heikki Tuuri
  18. ***********************************************************************/
  19. #ifndef UNIV_INNOCHECKSUM
  20. #include "ut0mem.h"
  21. /*******************************************************//**
  22. The following function is used to store data in one byte. */
  23. UNIV_INLINE
  24. void
  25. mach_write_to_1(
  26. /*============*/
  27. byte* b, /*!< in: pointer to byte where to store */
  28. ulint n) /*!< in: ulint integer to be stored, >= 0, < 256 */
  29. {
  30. ut_ad(b);
  31. ut_ad((n | 0xFFUL) <= 0xFFUL);
  32. b[0] = (byte) n;
  33. }
  34. /********************************************************//**
  35. The following function is used to fetch data from one byte.
  36. @return ulint integer, >= 0, < 256 */
  37. UNIV_INLINE
  38. ulint
  39. mach_read_from_1(
  40. /*=============*/
  41. const byte* b) /*!< in: pointer to byte */
  42. {
  43. ut_ad(b);
  44. return((ulint)(b[0]));
  45. }
  46. /*******************************************************//**
  47. The following function is used to store data in two consecutive
  48. bytes. We store the most significant byte to the lowest address. */
  49. UNIV_INLINE
  50. void
  51. mach_write_to_2(
  52. /*============*/
  53. byte* b, /*!< in: pointer to two bytes where to store */
  54. ulint n) /*!< in: ulint integer to be stored */
  55. {
  56. ut_ad(b);
  57. ut_ad((n | 0xFFFFUL) <= 0xFFFFUL);
  58. b[0] = (byte)(n >> 8);
  59. b[1] = (byte)(n);
  60. }
  61. /********************************************************//**
  62. The following function is used to convert a 16-bit data item
  63. to the canonical format, for fast bytewise equality test
  64. against memory.
  65. @return 16-bit integer in canonical format */
  66. UNIV_INLINE
  67. uint16
  68. mach_encode_2(
  69. /*==========*/
  70. ulint n) /*!< in: integer in machine-dependent format */
  71. {
  72. uint16 ret;
  73. ut_ad(2 == sizeof ret);
  74. mach_write_to_2((byte*) &ret, n);
  75. return(ret);
  76. }
  77. /********************************************************//**
  78. The following function is used to convert a 16-bit data item
  79. from the canonical format, for fast bytewise equality test
  80. against memory.
  81. @return integer in machine-dependent format */
  82. UNIV_INLINE
  83. ulint
  84. mach_decode_2(
  85. /*==========*/
  86. uint16 n) /*!< in: 16-bit integer in canonical format */
  87. {
  88. ut_ad(2 == sizeof n);
  89. return(mach_read_from_2((const byte*) &n));
  90. }
  91. /*******************************************************//**
  92. The following function is used to store data in 3 consecutive
  93. bytes. We store the most significant byte to the lowest address. */
  94. UNIV_INLINE
  95. void
  96. mach_write_to_3(
  97. /*============*/
  98. byte* b, /*!< in: pointer to 3 bytes where to store */
  99. ulint n) /*!< in: ulint integer to be stored */
  100. {
  101. ut_ad(b);
  102. ut_ad((n | 0xFFFFFFUL) <= 0xFFFFFFUL);
  103. b[0] = (byte)(n >> 16);
  104. b[1] = (byte)(n >> 8);
  105. b[2] = (byte)(n);
  106. }
  107. /********************************************************//**
  108. The following function is used to fetch data from 3 consecutive
  109. bytes. The most significant byte is at the lowest address.
  110. @return ulint integer */
  111. UNIV_INLINE
  112. ulint
  113. mach_read_from_3(
  114. /*=============*/
  115. const byte* b) /*!< in: pointer to 3 bytes */
  116. {
  117. ut_ad(b);
  118. return( ((ulint)(b[0]) << 16)
  119. | ((ulint)(b[1]) << 8)
  120. | (ulint)(b[2])
  121. );
  122. }
  123. /*******************************************************//**
  124. The following function is used to store data in four consecutive
  125. bytes. We store the most significant byte to the lowest address. */
  126. UNIV_INLINE
  127. void
  128. mach_write_to_4(
  129. /*============*/
  130. byte* b, /*!< in: pointer to four bytes where to store */
  131. ulint n) /*!< in: ulint integer to be stored */
  132. {
  133. ut_ad(b);
  134. b[0] = (byte)(n >> 24);
  135. b[1] = (byte)(n >> 16);
  136. b[2] = (byte)(n >> 8);
  137. b[3] = (byte) n;
  138. }
  139. #endif /* !UNIV_INNOCHECKSUM */
  140. /********************************************************//**
  141. The following function is used to fetch data from 2 consecutive
  142. bytes. The most significant byte is at the lowest address.
  143. @return ulint integer */
  144. UNIV_INLINE
  145. ulint
  146. mach_read_from_2(
  147. /*=============*/
  148. const byte* b) /*!< in: pointer to 2 bytes */
  149. {
  150. return(((ulint)(b[0]) << 8) | (ulint)(b[1]));
  151. }
  152. /********************************************************//**
  153. The following function is used to fetch data from 4 consecutive
  154. bytes. The most significant byte is at the lowest address.
  155. @return ulint integer */
  156. UNIV_INLINE
  157. ulint
  158. mach_read_from_4(
  159. /*=============*/
  160. const byte* b) /*!< in: pointer to four bytes */
  161. {
  162. ut_ad(b);
  163. return( ((ulint)(b[0]) << 24)
  164. | ((ulint)(b[1]) << 16)
  165. | ((ulint)(b[2]) << 8)
  166. | (ulint)(b[3])
  167. );
  168. }
  169. #ifndef UNIV_INNOCHECKSUM
  170. /*********************************************************//**
  171. Writes a ulint in a compressed form where the first byte codes the
  172. length of the stored ulint. We look at the most significant bits of
  173. the byte. If the most significant bit is zero, it means 1-byte storage,
  174. else if the 2nd bit is 0, it means 2-byte storage, else if 3rd is 0,
  175. it means 3-byte storage, else if 4th is 0, it means 4-byte storage,
  176. else the storage is 5-byte.
  177. @return compressed size in bytes */
  178. UNIV_INLINE
  179. ulint
  180. mach_write_compressed(
  181. /*==================*/
  182. byte* b, /*!< in: pointer to memory where to store */
  183. ulint n) /*!< in: ulint integer (< 2^32) to be stored */
  184. {
  185. ut_ad(b);
  186. if (n < 0x80UL) {
  187. mach_write_to_1(b, n);
  188. return(1);
  189. } else if (n < 0x4000UL) {
  190. mach_write_to_2(b, n | 0x8000UL);
  191. return(2);
  192. } else if (n < 0x200000UL) {
  193. mach_write_to_3(b, n | 0xC00000UL);
  194. return(3);
  195. } else if (n < 0x10000000UL) {
  196. mach_write_to_4(b, n | 0xE0000000UL);
  197. return(4);
  198. } else {
  199. mach_write_to_1(b, 0xF0UL);
  200. mach_write_to_4(b + 1, n);
  201. return(5);
  202. }
  203. }
  204. /*********************************************************//**
  205. Returns the size of a ulint when written in the compressed form.
  206. @return compressed size in bytes */
  207. UNIV_INLINE
  208. ulint
  209. mach_get_compressed_size(
  210. /*=====================*/
  211. ulint n) /*!< in: ulint integer (< 2^32) to be stored */
  212. {
  213. if (n < 0x80UL) {
  214. return(1);
  215. } else if (n < 0x4000UL) {
  216. return(2);
  217. } else if (n < 0x200000UL) {
  218. return(3);
  219. } else if (n < 0x10000000UL) {
  220. return(4);
  221. } else {
  222. return(5);
  223. }
  224. }
  225. /*********************************************************//**
  226. Reads a ulint in a compressed form.
  227. @return read integer (< 2^32) */
  228. UNIV_INLINE
  229. ulint
  230. mach_read_compressed(
  231. /*=================*/
  232. const byte* b) /*!< in: pointer to memory from where to read */
  233. {
  234. ulint flag;
  235. ut_ad(b);
  236. flag = mach_read_from_1(b);
  237. if (flag < 0x80UL) {
  238. return(flag);
  239. } else if (flag < 0xC0UL) {
  240. return(mach_read_from_2(b) & 0x7FFFUL);
  241. } else if (flag < 0xE0UL) {
  242. return(mach_read_from_3(b) & 0x3FFFFFUL);
  243. } else if (flag < 0xF0UL) {
  244. return(mach_read_from_4(b) & 0x1FFFFFFFUL);
  245. } else {
  246. ut_ad(flag == 0xF0UL);
  247. return(mach_read_from_4(b + 1));
  248. }
  249. }
  250. /*******************************************************//**
  251. The following function is used to store data in 8 consecutive
  252. bytes. We store the most significant byte to the lowest address. */
  253. UNIV_INLINE
  254. void
  255. mach_write_to_8(
  256. /*============*/
  257. void* b, /*!< in: pointer to 8 bytes where to store */
  258. ib_uint64_t n) /*!< in: 64-bit integer to be stored */
  259. {
  260. ut_ad(b);
  261. mach_write_to_4(static_cast<byte*>(b), (ulint) (n >> 32));
  262. mach_write_to_4(static_cast<byte*>(b) + 4, (ulint) n);
  263. }
  264. /********************************************************//**
  265. The following function is used to fetch data from 8 consecutive
  266. bytes. The most significant byte is at the lowest address.
  267. @return 64-bit integer */
  268. UNIV_INLINE
  269. ib_uint64_t
  270. mach_read_from_8(
  271. /*=============*/
  272. const byte* b) /*!< in: pointer to 8 bytes */
  273. {
  274. ib_uint64_t ull;
  275. ull = ((ib_uint64_t) mach_read_from_4(b)) << 32;
  276. ull |= (ib_uint64_t) mach_read_from_4(b + 4);
  277. return(ull);
  278. }
  279. /*******************************************************//**
  280. The following function is used to store data in 7 consecutive
  281. bytes. We store the most significant byte to the lowest address. */
  282. UNIV_INLINE
  283. void
  284. mach_write_to_7(
  285. /*============*/
  286. byte* b, /*!< in: pointer to 7 bytes where to store */
  287. ib_uint64_t n) /*!< in: 56-bit integer */
  288. {
  289. ut_ad(b);
  290. mach_write_to_3(b, (ulint) (n >> 32));
  291. mach_write_to_4(b + 3, (ulint) n);
  292. }
  293. /********************************************************//**
  294. The following function is used to fetch data from 7 consecutive
  295. bytes. The most significant byte is at the lowest address.
  296. @return 56-bit integer */
  297. UNIV_INLINE
  298. ib_uint64_t
  299. mach_read_from_7(
  300. /*=============*/
  301. const byte* b) /*!< in: pointer to 7 bytes */
  302. {
  303. ut_ad(b);
  304. return(ut_ull_create(mach_read_from_3(b), mach_read_from_4(b + 3)));
  305. }
  306. /*******************************************************//**
  307. The following function is used to store data in 6 consecutive
  308. bytes. We store the most significant byte to the lowest address. */
  309. UNIV_INLINE
  310. void
  311. mach_write_to_6(
  312. /*============*/
  313. byte* b, /*!< in: pointer to 6 bytes where to store */
  314. ib_uint64_t n) /*!< in: 48-bit integer */
  315. {
  316. ut_ad(b);
  317. mach_write_to_2(b, (ulint) (n >> 32));
  318. mach_write_to_4(b + 2, (ulint) n);
  319. }
  320. /********************************************************//**
  321. The following function is used to fetch data from 6 consecutive
  322. bytes. The most significant byte is at the lowest address.
  323. @return 48-bit integer */
  324. UNIV_INLINE
  325. ib_uint64_t
  326. mach_read_from_6(
  327. /*=============*/
  328. const byte* b) /*!< in: pointer to 6 bytes */
  329. {
  330. ut_ad(b);
  331. return(ut_ull_create(mach_read_from_2(b), mach_read_from_4(b + 2)));
  332. }
  333. /*********************************************************//**
  334. Writes a 64-bit integer in a compressed form (5..9 bytes).
  335. @return size in bytes */
  336. UNIV_INLINE
  337. ulint
  338. mach_ull_write_compressed(
  339. /*======================*/
  340. byte* b, /*!< in: pointer to memory where to store */
  341. ib_uint64_t n) /*!< in: 64-bit integer to be stored */
  342. {
  343. ulint size;
  344. ut_ad(b);
  345. size = mach_write_compressed(b, (ulint) (n >> 32));
  346. mach_write_to_4(b + size, (ulint) n);
  347. return(size + 4);
  348. }
  349. /*********************************************************//**
  350. Returns the size of a 64-bit integer when written in the compressed form.
  351. @return compressed size in bytes */
  352. UNIV_INLINE
  353. ulint
  354. mach_ull_get_compressed_size(
  355. /*=========================*/
  356. ib_uint64_t n) /*!< in: 64-bit integer to be stored */
  357. {
  358. return(4 + mach_get_compressed_size((ulint) (n >> 32)));
  359. }
  360. /*********************************************************//**
  361. Reads a 64-bit integer in a compressed form.
  362. @return the value read */
  363. UNIV_INLINE
  364. ib_uint64_t
  365. mach_ull_read_compressed(
  366. /*=====================*/
  367. const byte* b) /*!< in: pointer to memory from where to read */
  368. {
  369. ib_uint64_t n;
  370. ulint size;
  371. ut_ad(b);
  372. n = (ib_uint64_t) mach_read_compressed(b);
  373. size = mach_get_compressed_size((ulint) n);
  374. n <<= 32;
  375. n |= (ib_uint64_t) mach_read_from_4(b + size);
  376. return(n);
  377. }
  378. /*********************************************************//**
  379. Writes a 64-bit integer in a compressed form (1..11 bytes).
  380. @return size in bytes */
  381. UNIV_INLINE
  382. ulint
  383. mach_ull_write_much_compressed(
  384. /*===========================*/
  385. byte* b, /*!< in: pointer to memory where to store */
  386. ib_uint64_t n) /*!< in: 64-bit integer to be stored */
  387. {
  388. ulint size;
  389. ut_ad(b);
  390. if (!(n >> 32)) {
  391. return(mach_write_compressed(b, (ulint) n));
  392. }
  393. *b = (byte)0xFF;
  394. size = 1 + mach_write_compressed(b + 1, (ulint) (n >> 32));
  395. size += mach_write_compressed(b + size, (ulint) n & 0xFFFFFFFF);
  396. return(size);
  397. }
  398. /*********************************************************//**
  399. Returns the size of a 64-bit integer when written in the compressed form.
  400. @return compressed size in bytes */
  401. UNIV_INLINE
  402. ulint
  403. mach_ull_get_much_compressed_size(
  404. /*==============================*/
  405. ib_uint64_t n) /*!< in: 64-bit integer to be stored */
  406. {
  407. if (!(n >> 32)) {
  408. return(mach_get_compressed_size((ulint) n));
  409. }
  410. return(1 + mach_get_compressed_size((ulint) (n >> 32))
  411. + mach_get_compressed_size((ulint) n & ULINT32_MASK));
  412. }
  413. /*********************************************************//**
  414. Reads a 64-bit integer in a compressed form.
  415. @return the value read */
  416. UNIV_INLINE
  417. ib_uint64_t
  418. mach_ull_read_much_compressed(
  419. /*==========================*/
  420. const byte* b) /*!< in: pointer to memory from where to read */
  421. {
  422. ib_uint64_t n;
  423. ulint size;
  424. ut_ad(b);
  425. if (*b != (byte)0xFF) {
  426. n = 0;
  427. size = 0;
  428. } else {
  429. n = (ib_uint64_t) mach_read_compressed(b + 1);
  430. size = 1 + mach_get_compressed_size((ulint) n);
  431. n <<= 32;
  432. }
  433. n |= mach_read_compressed(b + size);
  434. return(n);
  435. }
  436. /*********************************************************//**
  437. Reads a 64-bit integer in a compressed form
  438. if the log record fully contains it.
  439. @return pointer to end of the stored field, NULL if not complete */
  440. UNIV_INLINE
  441. byte*
  442. mach_ull_parse_compressed(
  443. /*======================*/
  444. byte* ptr, /* in: pointer to buffer from where to read */
  445. byte* end_ptr,/* in: pointer to end of the buffer */
  446. ib_uint64_t* val) /* out: read value */
  447. {
  448. ulint size;
  449. ut_ad(ptr);
  450. ut_ad(end_ptr);
  451. ut_ad(val);
  452. if (end_ptr < ptr + 5) {
  453. return(NULL);
  454. }
  455. *val = mach_read_compressed(ptr);
  456. size = mach_get_compressed_size((ulint) *val);
  457. ptr += size;
  458. if (end_ptr < ptr + 4) {
  459. return(NULL);
  460. }
  461. *val <<= 32;
  462. *val |= mach_read_from_4(ptr);
  463. return(ptr + 4);
  464. }
  465. #ifndef UNIV_HOTBACKUP
  466. /*********************************************************//**
  467. Reads a double. It is stored in a little-endian format.
  468. @return double read */
  469. UNIV_INLINE
  470. double
  471. mach_double_read(
  472. /*=============*/
  473. const byte* b) /*!< in: pointer to memory from where to read */
  474. {
  475. double d;
  476. ulint i;
  477. byte* ptr;
  478. ptr = (byte*) &d;
  479. for (i = 0; i < sizeof(double); i++) {
  480. #ifdef WORDS_BIGENDIAN
  481. ptr[sizeof(double) - i - 1] = b[i];
  482. #else
  483. ptr[i] = b[i];
  484. #endif
  485. }
  486. return(d);
  487. }
  488. /*********************************************************//**
  489. Writes a double. It is stored in a little-endian format. */
  490. UNIV_INLINE
  491. void
  492. mach_double_write(
  493. /*==============*/
  494. byte* b, /*!< in: pointer to memory where to write */
  495. double d) /*!< in: double */
  496. {
  497. ulint i;
  498. byte* ptr;
  499. ptr = (byte*) &d;
  500. for (i = 0; i < sizeof(double); i++) {
  501. #ifdef WORDS_BIGENDIAN
  502. b[i] = ptr[sizeof(double) - i - 1];
  503. #else
  504. b[i] = ptr[i];
  505. #endif
  506. }
  507. }
  508. /*********************************************************//**
  509. Reads a float. It is stored in a little-endian format.
  510. @return float read */
  511. UNIV_INLINE
  512. float
  513. mach_float_read(
  514. /*============*/
  515. const byte* b) /*!< in: pointer to memory from where to read */
  516. {
  517. float d;
  518. ulint i;
  519. byte* ptr;
  520. ptr = (byte*) &d;
  521. for (i = 0; i < sizeof(float); i++) {
  522. #ifdef WORDS_BIGENDIAN
  523. ptr[sizeof(float) - i - 1] = b[i];
  524. #else
  525. ptr[i] = b[i];
  526. #endif
  527. }
  528. return(d);
  529. }
  530. /*********************************************************//**
  531. Writes a float. It is stored in a little-endian format. */
  532. UNIV_INLINE
  533. void
  534. mach_float_write(
  535. /*=============*/
  536. byte* b, /*!< in: pointer to memory where to write */
  537. float d) /*!< in: float */
  538. {
  539. ulint i;
  540. byte* ptr;
  541. ptr = (byte*) &d;
  542. for (i = 0; i < sizeof(float); i++) {
  543. #ifdef WORDS_BIGENDIAN
  544. b[i] = ptr[sizeof(float) - i - 1];
  545. #else
  546. b[i] = ptr[i];
  547. #endif
  548. }
  549. }
  550. /*********************************************************//**
  551. Reads a ulint stored in the little-endian format.
  552. @return unsigned long int */
  553. UNIV_INLINE
  554. ulint
  555. mach_read_from_n_little_endian(
  556. /*===========================*/
  557. const byte* buf, /*!< in: from where to read */
  558. ulint buf_size) /*!< in: from how many bytes to read */
  559. {
  560. ulint n = 0;
  561. const byte* ptr;
  562. ut_ad(buf_size > 0);
  563. ptr = buf + buf_size;
  564. for (;;) {
  565. ptr--;
  566. n = n << 8;
  567. n += (ulint)(*ptr);
  568. if (ptr == buf) {
  569. break;
  570. }
  571. }
  572. return(n);
  573. }
  574. /*********************************************************//**
  575. Writes a ulint in the little-endian format. */
  576. UNIV_INLINE
  577. void
  578. mach_write_to_n_little_endian(
  579. /*==========================*/
  580. byte* dest, /*!< in: where to write */
  581. ulint dest_size, /*!< in: into how many bytes to write */
  582. ulint n) /*!< in: unsigned long int to write */
  583. {
  584. byte* end;
  585. ut_ad(dest_size <= sizeof(ulint));
  586. ut_ad(dest_size > 0);
  587. end = dest + dest_size;
  588. for (;;) {
  589. *dest = (byte)(n & 0xFF);
  590. n = n >> 8;
  591. dest++;
  592. if (dest == end) {
  593. break;
  594. }
  595. }
  596. ut_ad(n == 0);
  597. }
  598. /*********************************************************//**
  599. Reads a ulint stored in the little-endian format.
  600. @return unsigned long int */
  601. UNIV_INLINE
  602. ulint
  603. mach_read_from_2_little_endian(
  604. /*===========================*/
  605. const byte* buf) /*!< in: from where to read */
  606. {
  607. return((ulint)(buf[0]) | ((ulint)(buf[1]) << 8));
  608. }
  609. /*********************************************************//**
  610. Writes a ulint in the little-endian format. */
  611. UNIV_INLINE
  612. void
  613. mach_write_to_2_little_endian(
  614. /*==========================*/
  615. byte* dest, /*!< in: where to write */
  616. ulint n) /*!< in: unsigned long int to write */
  617. {
  618. ut_ad(n < 256 * 256);
  619. *dest = (byte)(n & 0xFFUL);
  620. n = n >> 8;
  621. dest++;
  622. *dest = (byte)(n & 0xFFUL);
  623. }
  624. /*********************************************************//**
  625. Convert integral type from storage byte order (big endian) to
  626. host byte order.
  627. @return integer value */
  628. UNIV_INLINE
  629. ib_uint64_t
  630. mach_read_int_type(
  631. /*===============*/
  632. const byte* src, /*!< in: where to read from */
  633. ulint len, /*!< in: length of src */
  634. ibool unsigned_type) /*!< in: signed or unsigned flag */
  635. {
  636. /* XXX this can be optimized on big-endian machines */
  637. ullint ret;
  638. uint i;
  639. if (unsigned_type || (src[0] & 0x80)) {
  640. ret = 0x0000000000000000ULL;
  641. } else {
  642. ret = 0xFFFFFFFFFFFFFF00ULL;
  643. }
  644. if (unsigned_type) {
  645. ret |= src[0];
  646. } else {
  647. ret |= src[0] ^ 0x80;
  648. }
  649. for (i = 1; i < len; i++) {
  650. ret <<= 8;
  651. ret |= src[i];
  652. }
  653. return(ret);
  654. }
  655. /*********************************************************//**
  656. Swap byte ordering. */
  657. UNIV_INLINE
  658. void
  659. mach_swap_byte_order(
  660. /*=================*/
  661. byte* dest, /*!< out: where to write */
  662. const byte* from, /*!< in: where to read from */
  663. ulint len) /*!< in: length of src */
  664. {
  665. ut_ad(len > 0);
  666. ut_ad(len <= 8);
  667. dest += len;
  668. switch (len & 0x7) {
  669. case 0: *--dest = *from++;
  670. case 7: *--dest = *from++;
  671. case 6: *--dest = *from++;
  672. case 5: *--dest = *from++;
  673. case 4: *--dest = *from++;
  674. case 3: *--dest = *from++;
  675. case 2: *--dest = *from++;
  676. case 1: *--dest = *from;
  677. }
  678. }
  679. /*************************************************************
  680. Convert integral type from host byte order (big-endian) storage
  681. byte order. */
  682. UNIV_INLINE
  683. void
  684. mach_write_int_type(
  685. /*================*/
  686. byte* dest, /*!< in: where to write */
  687. const byte* src, /*!< in: where to read from */
  688. ulint len, /*!< in: length of src */
  689. bool usign) /*!< in: signed or unsigned flag */
  690. {
  691. #ifdef WORDS_BIGENDIAN
  692. memcpy(dest, src, len);
  693. #else
  694. mach_swap_byte_order(dest, src, len);
  695. #endif /* WORDS_BIGENDIAN */
  696. if (!usign) {
  697. *dest ^= 0x80;
  698. }
  699. }
  700. /*************************************************************
  701. Convert a ulonglong integer from host byte order to (big-endian)
  702. storage byte order. */
  703. UNIV_INLINE
  704. void
  705. mach_write_ulonglong(
  706. /*=================*/
  707. byte* dest, /*!< in: where to write */
  708. ulonglong src, /*!< in: where to read from */
  709. ulint len, /*!< in: length of dest */
  710. bool usign) /*!< in: signed or unsigned flag */
  711. {
  712. byte* ptr = reinterpret_cast<byte*>(&src);
  713. ut_ad(len <= sizeof(ulonglong));
  714. #ifdef WORDS_BIGENDIAN
  715. memcpy(dest, ptr + (sizeof(src) - len), len);
  716. #else
  717. mach_swap_byte_order(dest, reinterpret_cast<byte*>(ptr), len);
  718. #endif /* WORDS_BIGENDIAN */
  719. if (!usign) {
  720. *dest ^= 0x80;
  721. }
  722. }
  723. /********************************************************//**
  724. Reads 1 - 4 bytes from a file page buffered in the buffer pool.
  725. @return value read */
  726. UNIV_INLINE
  727. ulint
  728. mach_read_ulint(
  729. /*============*/
  730. const byte* ptr, /*!< in: pointer from where to read */
  731. ulint type) /*!< in: 1,2 or 4 bytes */
  732. {
  733. switch (type) {
  734. case 1:
  735. return(mach_read_from_1(ptr));
  736. case 2:
  737. return(mach_read_from_2(ptr));
  738. case 4:
  739. return(mach_read_from_4(ptr));
  740. default:
  741. ut_error;
  742. }
  743. return(0);
  744. }
  745. #endif /* !UNIV_HOTBACKUP */
  746. #endif /* !UNIV_INNOCHECKSUM */