mach0data.ic
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:16k
- /**********************************************************************
- Utilities for converting data from the database file
- to the machine format.
- (c) 1995 Innobase Oy
- Created 11/28/1995 Heikki Tuuri
- ***********************************************************************/
- /***********************************************************
- The following function is used to store data in one byte. */
- UNIV_INLINE
- void
- mach_write_to_1(
- /*============*/
- byte* b, /* in: pointer to byte where to store */
- ulint n) /* in: ulint integer to be stored, >= 0, < 256 */
- {
- ut_ad(b);
- ut_ad(n <= 0xFF);
- b[0] = (byte)n;
- }
- /************************************************************
- The following function is used to fetch data from one byte. */
- UNIV_INLINE
- ulint
- mach_read_from_1(
- /*=============*/
- /* out: ulint integer, >= 0, < 256 */
- byte* b) /* in: pointer to byte */
- {
- ut_ad(b);
- return((ulint)(b[0]));
- }
- /***********************************************************
- The following function is used to store data in two consecutive
- bytes. We store the most significant byte to the lowest address. */
- UNIV_INLINE
- void
- mach_write_to_2(
- /*============*/
- byte* b, /* in: pointer to two bytes where to store */
- ulint n) /* in: ulint integer to be stored */
- {
- ut_ad(b);
- ut_ad(n <= 0xFFFF);
- b[0] = (byte)(n >> 8);
- b[1] = (byte)(n);
- }
- /************************************************************
- The following function is used to fetch data from 2 consecutive
- bytes. The most significant byte is at the lowest address. */
- UNIV_INLINE
- ulint
- mach_read_from_2(
- /*=============*/
- /* out: ulint integer */
- byte* b) /* in: pointer to 2 bytes */
- {
- ut_ad(b);
- return( ((ulint)(b[0]) << 8)
- + (ulint)(b[1])
- );
- }
- /***********************************************************
- The following function is used to store data in 3 consecutive
- bytes. We store the most significant byte to the lowest address. */
- UNIV_INLINE
- void
- mach_write_to_3(
- /*============*/
- byte* b, /* in: pointer to 3 bytes where to store */
- ulint n) /* in: ulint integer to be stored */
- {
- ut_ad(b);
- ut_ad(n <= 0xFFFFFF);
- b[0] = (byte)(n >> 16);
- b[1] = (byte)(n >> 8);
- b[2] = (byte)(n);
- }
- /************************************************************
- The following function is used to fetch data from 3 consecutive
- bytes. The most significant byte is at the lowest address. */
- UNIV_INLINE
- ulint
- mach_read_from_3(
- /*=============*/
- /* out: ulint integer */
- byte* b) /* in: pointer to 3 bytes */
- {
- ut_ad(b);
- return( ((ulint)(b[0]) << 16)
- + ((ulint)(b[1]) << 8)
- + (ulint)(b[2])
- );
- }
- /***********************************************************
- The following function is used to store data in four consecutive
- bytes. We store the most significant byte to the lowest address. */
- UNIV_INLINE
- void
- mach_write_to_4(
- /*============*/
- byte* b, /* in: pointer to four bytes where to store */
- ulint n) /* in: ulint integer to be stored */
- {
- ut_ad(b);
- #if notdefined && !defined(__STDC__) && defined(UNIV_INTEL) && (UNIV_WORD_SIZE == 4) && defined(UNIV_VISUALC)
- /* We do not use this even on Intel, because unaligned accesses may
- be slow */
- __asm MOV EAX, n
- __asm BSWAP EAX /* Intel is little-endian, must swap bytes */
- __asm MOV n, EAX
-
- *((ulint*)b) = n;
- #else
- b[0] = (byte)(n >> 24);
- b[1] = (byte)(n >> 16);
- b[2] = (byte)(n >> 8);
- b[3] = (byte)n;
- #endif
- }
- /************************************************************
- The following function is used to fetch data from 4 consecutive
- bytes. The most significant byte is at the lowest address. */
- UNIV_INLINE
- ulint
- mach_read_from_4(
- /*=============*/
- /* out: ulint integer */
- byte* b) /* in: pointer to four bytes */
- {
- #if notdefined && !defined(__STDC__) && defined(UNIV_INTEL) && (UNIV_WORD_SIZE == 4) && defined(UNIV_VISUALC)
- /* We do not use this even on Intel, because unaligned accesses may
- be slow */
- ulint res;
- ut_ad(b);
- __asm MOV EDX, b
- __asm MOV ECX, DWORD PTR [EDX]
- __asm BSWAP ECX /* Intel is little-endian, must swap bytes */
- __asm MOV res, ECX
- return(res);
- #else
- ut_ad(b);
- return( ((ulint)(b[0]) << 24)
- + ((ulint)(b[1]) << 16)
- + ((ulint)(b[2]) << 8)
- + (ulint)(b[3])
- );
- #endif
- }
- /***********************************************************
- The following function is used to store data from a ulint to memory
- in standard order: we store the most significant byte to the lowest
- address. */
- UNIV_INLINE
- void
- mach_write(
- /*=======*/
- byte* b, /* in: pointer to 4 bytes where to store */
- ulint n) /* in: ulint integer to be stored */
- {
- ut_ad(b);
- b[0] = (byte)(n >> 24);
- b[1] = (byte)(n >> 16);
- b[2] = (byte)(n >> 8);
- b[3] = (byte)n;
- }
- /************************************************************
- The following function is used to fetch data from memory to a ulint.
- The most significant byte is at the lowest address. */
- UNIV_INLINE
- ulint
- mach_read(
- /*======*/
- /* out: ulint integer */
- byte* b) /* in: pointer to 4 bytes */
- {
- ut_ad(b);
- return( ((ulint)(b[0]) << 24)
- + ((ulint)(b[1]) << 16)
- + ((ulint)(b[2]) << 8)
- + (ulint)(b[3])
- );
- }
- /*************************************************************
- Writes a ulint in a compressed form where the first byte codes the
- length of the stored ulint. We look at the most significant bits of
- the byte. If the most significant bit is zero, it means 1-byte storage,
- else if the 2nd bit is 0, it means 2-byte storage, else if 3rd is 0,
- it means 3-byte storage, else if 4th is 0, it means 4-byte storage,
- else the storage is 5-byte. */
- UNIV_INLINE
- ulint
- mach_write_compressed(
- /*==================*/
- /* out: compressed size in bytes */
- byte* b, /* in: pointer to memory where to store */
- ulint n) /* in: ulint integer (< 2^32) to be stored */
- {
- ut_ad(b);
- if (n < 0x80) {
- mach_write_to_1(b, n);
- return(1);
- } else if (n < 0x4000) {
- mach_write_to_2(b, n | 0x8000);
- return(2);
- } else if (n < 0x200000) {
- mach_write_to_3(b, n | 0xC00000);
- return(3);
- } else if (n < 0x10000000) {
- mach_write_to_4(b, n | 0xE0000000);
- return(4);
- } else {
- mach_write_to_1(b, 0xF0);
- mach_write_to_4(b + 1, n);
- return(5);
- }
- }
- /*************************************************************
- Returns the size of a ulint when written in the compressed form. */
- UNIV_INLINE
- ulint
- mach_get_compressed_size(
- /*=====================*/
- /* out: compressed size in bytes */
- ulint n) /* in: ulint integer (< 2^32) to be stored */
- {
- if (n < 0x80) {
- return(1);
- } else if (n < 0x4000) {
- return(2);
- } else if (n < 0x200000) {
- return(3);
- } else if (n < 0x10000000) {
- return(4);
- } else {
- return(5);
- }
- }
- /*************************************************************
- Reads a ulint in a compressed form. */
- UNIV_INLINE
- ulint
- mach_read_compressed(
- /*=================*/
- /* out: read integer (< 2^32) */
- byte* b) /* in: pointer to memory from where to read */
- {
- ulint flag;
- ut_ad(b);
- flag = mach_read_from_1(b);
- if (flag < 0x80) {
- return(flag);
- } else if (flag < 0xC0) {
- return(mach_read_from_2(b) & 0x7FFF);
- } else if (flag < 0xE0) {
- return(mach_read_from_3(b) & 0x3FFFFF);
- } else if (flag < 0xF0) {
- return(mach_read_from_4(b) & 0x1FFFFFFF);
- } else {
- ut_ad(flag == 0xF0);
- return(mach_read_from_4(b + 1));
- }
- }
- /***********************************************************
- The following function is used to store data in 8 consecutive
- bytes. We store the most significant byte to the lowest address. */
- UNIV_INLINE
- void
- mach_write_to_8(
- /*============*/
- byte* b, /* in: pointer to 8 bytes where to store */
- dulint n) /* in: dulint integer to be stored */
- {
- ut_ad(b);
- mach_write_to_4(b, ut_dulint_get_high(n));
- mach_write_to_4(b + 4, ut_dulint_get_low(n));
- }
- /************************************************************
- The following function is used to fetch data from 8 consecutive
- bytes. The most significant byte is at the lowest address. */
- UNIV_INLINE
- dulint
- mach_read_from_8(
- /*=============*/
- /* out: dulint integer */
- byte* b) /* in: pointer to 8 bytes */
- {
- ulint high;
- ulint low;
- ut_ad(b);
- high = mach_read_from_4(b);
- low = mach_read_from_4(b + 4);
- return(ut_dulint_create(high, low));
- }
- /***********************************************************
- The following function is used to store data in 7 consecutive
- bytes. We store the most significant byte to the lowest address. */
- UNIV_INLINE
- void
- mach_write_to_7(
- /*============*/
- byte* b, /* in: pointer to 7 bytes where to store */
- dulint n) /* in: dulint integer to be stored */
- {
- ut_ad(b);
- mach_write_to_3(b, ut_dulint_get_high(n));
- mach_write_to_4(b + 3, ut_dulint_get_low(n));
- }
- /************************************************************
- The following function is used to fetch data from 7 consecutive
- bytes. The most significant byte is at the lowest address. */
- UNIV_INLINE
- dulint
- mach_read_from_7(
- /*=============*/
- /* out: dulint integer */
- byte* b) /* in: pointer to 7 bytes */
- {
- ulint high;
- ulint low;
- ut_ad(b);
- high = mach_read_from_3(b);
- low = mach_read_from_4(b + 3);
- return(ut_dulint_create(high, low));
- }
- /***********************************************************
- The following function is used to store data in 6 consecutive
- bytes. We store the most significant byte to the lowest address. */
- UNIV_INLINE
- void
- mach_write_to_6(
- /*============*/
- byte* b, /* in: pointer to 6 bytes where to store */
- dulint n) /* in: dulint integer to be stored */
- {
- ut_ad(b);
- mach_write_to_2(b, ut_dulint_get_high(n));
- mach_write_to_4(b + 2, ut_dulint_get_low(n));
- }
- /************************************************************
- The following function is used to fetch data from 6 consecutive
- bytes. The most significant byte is at the lowest address. */
- UNIV_INLINE
- dulint
- mach_read_from_6(
- /*=============*/
- /* out: dulint integer */
- byte* b) /* in: pointer to 7 bytes */
- {
- ulint high;
- ulint low;
- ut_ad(b);
- high = mach_read_from_2(b);
- low = mach_read_from_4(b + 2);
- return(ut_dulint_create(high, low));
- }
- /*************************************************************
- Writes a dulint in a compressed form. */
- UNIV_INLINE
- ulint
- mach_dulint_write_compressed(
- /*=========================*/
- /* out: size in bytes */
- byte* b, /* in: pointer to memory where to store */
- dulint n) /* in: dulint integer to be stored */
- {
- ulint size;
- ut_ad(b);
- size = mach_write_compressed(b, ut_dulint_get_high(n));
- mach_write_to_4(b + size, ut_dulint_get_low(n));
- return(size + 4);
- }
- /*************************************************************
- Returns the size of a dulint when written in the compressed form. */
- UNIV_INLINE
- ulint
- mach_dulint_get_compressed_size(
- /*============================*/
- /* out: compressed size in bytes */
- dulint n) /* in: dulint integer to be stored */
- {
- return(4 + mach_get_compressed_size(ut_dulint_get_high(n)));
- }
- /*************************************************************
- Reads a dulint in a compressed form. */
- UNIV_INLINE
- dulint
- mach_dulint_read_compressed(
- /*========================*/
- /* out: read dulint */
- byte* b) /* in: pointer to memory from where to read */
- {
- ulint high;
- ulint low;
- ulint size;
- ut_ad(b);
- high = mach_read_compressed(b);
- size = mach_get_compressed_size(high);
- low = mach_read_from_4(b + size);
- return(ut_dulint_create(high, low));
- }
- /*************************************************************
- Writes a dulint in a compressed form. */
- UNIV_INLINE
- ulint
- mach_dulint_write_much_compressed(
- /*==============================*/
- /* out: size in bytes */
- byte* b, /* in: pointer to memory where to store */
- dulint n) /* in: dulint integer to be stored */
- {
- ulint size;
- ut_ad(b);
-
- if (ut_dulint_get_high(n) == 0) {
- return(mach_write_compressed(b, ut_dulint_get_low(n)));
- }
-
- *b = 0xFF;
- size = 1 + mach_write_compressed(b + 1, ut_dulint_get_high(n));
- size += mach_write_compressed(b + size, ut_dulint_get_low(n));
- return(size);
- }
- /*************************************************************
- Returns the size of a dulint when written in the compressed form. */
- UNIV_INLINE
- ulint
- mach_dulint_get_much_compressed_size(
- /*=================================*/
- /* out: compressed size in bytes */
- dulint n) /* in: dulint integer to be stored */
- {
- if (0 == ut_dulint_get_high(n)) {
- return(mach_get_compressed_size(ut_dulint_get_low(n)));
- }
- return(1 + mach_get_compressed_size(ut_dulint_get_high(n))
- + mach_get_compressed_size(ut_dulint_get_low(n)));
- }
- /*************************************************************
- Reads a dulint in a compressed form. */
- UNIV_INLINE
- dulint
- mach_dulint_read_much_compressed(
- /*=============================*/
- /* out: read dulint */
- byte* b) /* in: pointer to memory from where to read */
- {
- ulint high;
- ulint low;
- ulint size;
- ut_ad(b);
- if (*b != 0xFF) {
- high = 0;
- size = 0;
- } else {
- high = mach_read_compressed(b + 1);
- size = 1 + mach_get_compressed_size(high);
- }
- low = mach_read_compressed(b + size);
- return(ut_dulint_create(high, low));
- }
- /*************************************************************
- Reads a double. It is stored in a little-endian format. */
- UNIV_INLINE
- double
- mach_double_read(
- /*=============*/
- /* out: double read */
- byte* b) /* in: pointer to memory from where to read */
- {
- double d;
- ulint i;
- byte* ptr;
- ptr = (byte*)&d;
- for (i = 0; i < sizeof(double); i++) {
- #ifdef WORDS_BIGENDIAN
- ptr[sizeof(double) - i - 1] = b[i];
- #else
- ptr[i] = b[i];
- #endif
- }
- return(d);
- }
- /*************************************************************
- Writes a double. It is stored in a little-endian format. */
- UNIV_INLINE
- void
- mach_double_write(
- /*==============*/
- byte* b, /* in: pointer to memory where to write */
- double d) /* in: double */
- {
- ulint i;
- byte* ptr;
- ptr = (byte*)&d;
- for (i = 0; i < sizeof(double); i++) {
- #ifdef WORDS_BIGENDIAN
- b[i] = ptr[sizeof(double) - i - 1];
- #else
- b[i] = ptr[i];
- #endif
- }
- }
- /*************************************************************
- Reads a float. It is stored in a little-endian format. */
- UNIV_INLINE
- float
- mach_float_read(
- /*=============*/
- /* out: float read */
- byte* b) /* in: pointer to memory from where to read */
- {
- float d;
- ulint i;
- byte* ptr;
- ptr = (byte*)&d;
- for (i = 0; i < sizeof(float); i++) {
- #ifdef WORDS_BIGENDIAN
- ptr[sizeof(float) - i - 1] = b[i];
- #else
- ptr[i] = b[i];
- #endif
- }
- return(d);
- }
- /*************************************************************
- Writes a float. It is stored in a little-endian format. */
- UNIV_INLINE
- void
- mach_float_write(
- /*==============*/
- byte* b, /* in: pointer to memory where to write */
- float d) /* in: float */
- {
- ulint i;
- byte* ptr;
- ptr = (byte*)&d;
- for (i = 0; i < sizeof(float); i++) {
- #ifdef WORDS_BIGENDIAN
- b[i] = ptr[sizeof(float) - i - 1];
- #else
- b[i] = ptr[i];
- #endif
- }
- }
- /*************************************************************
- Reads a ulint stored in the little-endian format. */
- UNIV_INLINE
- ulint
- mach_read_from_n_little_endian(
- /*===========================*/
- /* out: unsigned long int */
- byte* buf, /* in: from where to read */
- ulint buf_size) /* in: from how many bytes to read */
- {
- ulint n = 0;
- byte* ptr;
- ut_ad(buf_size <= sizeof(ulint));
- ut_ad(buf_size > 0);
- ptr = buf + buf_size;
-
- for (;;) {
- ptr--;
- n = n << 8;
- n += (ulint)(*ptr);
- if (ptr == buf) {
- break;
- }
- }
- return(n);
- }
- /*************************************************************
- Writes a ulint in the little-endian format. */
- UNIV_INLINE
- void
- mach_write_to_n_little_endian(
- /*==========================*/
- byte* dest, /* in: where to write */
- ulint dest_size, /* in: into how many bytes to write */
- ulint n) /* in: unsigned long int to write */
- {
- byte* end;
- ut_ad(dest_size <= sizeof(ulint));
- ut_ad(dest_size > 0);
- end = dest + dest_size;
-
- for (;;) {
- *dest = (byte)(n & 0xFF);
- n = n >> 8;
- dest++;
- if (dest == end) {
- break;
- }
- }
- ut_ad(n == 0);
- }
- /*************************************************************
- Reads a ulint stored in the little-endian format. */
- UNIV_INLINE
- ulint
- mach_read_from_2_little_endian(
- /*===========================*/
- /* out: unsigned long int */
- byte* buf) /* in: from where to read */
- {
- return((ulint)(*buf) + ((ulint)(*(buf + 1))) * 256);
- }
- /*************************************************************
- Writes a ulint in the little-endian format. */
- UNIV_INLINE
- void
- mach_write_to_2_little_endian(
- /*==========================*/
- byte* dest, /* in: where to write */
- ulint n) /* in: unsigned long int to write */
- {
- ut_ad(n < 256 * 256);
- *dest = (byte)(n & 0xFF);
- n = n >> 8;
- dest++;
- *dest = (byte)(n & 0xFF);
- }