1
/**********************************************************************
2
Utilities for converting data from the database file
7
Created 11/28/1995 Heikki Tuuri
8
***********************************************************************/
12
/***********************************************************
13
The following function is used to store data in one byte. */
18
byte* b, /* in: pointer to byte where to store */
19
ulint n) /* in: ulint integer to be stored, >= 0, < 256 */
27
/************************************************************
28
The following function is used to fetch data from one byte. */
33
/* out: ulint integer, >= 0, < 256 */
34
byte* b) /* in: pointer to byte */
37
return((ulint)(b[0]));
40
/***********************************************************
41
The following function is used to store data in two consecutive
42
bytes. We store the most significant byte to the lowest address. */
47
byte* b, /* in: pointer to two bytes where to store */
48
ulint n) /* in: ulint integer to be stored */
53
b[0] = (byte)(n >> 8);
57
/************************************************************
58
The following function is used to fetch data from 2 consecutive
59
bytes. The most significant byte is at the lowest address. */
64
/* out: ulint integer */
65
byte* b) /* in: pointer to 2 bytes */
68
return( ((ulint)(b[0]) << 8)
73
/************************************************************
74
The following function is used to convert a 16-bit data item
75
to the canonical format, for fast bytewise equality test
81
/* out: 16-bit integer in canonical format */
82
ulint n) /* in: integer in machine-dependent format */
85
ut_ad(2 == sizeof ret);
86
mach_write_to_2((byte*) &ret, n);
89
/************************************************************
90
The following function is used to convert a 16-bit data item
91
from the canonical format, for fast bytewise equality test
97
/* out: integer in machine-dependent format */
98
uint16 n) /* in: 16-bit integer in canonical format */
100
ut_ad(2 == sizeof n);
101
return(mach_read_from_2((byte*) &n));
104
/***********************************************************
105
The following function is used to store data in 3 consecutive
106
bytes. We store the most significant byte to the lowest address. */
111
byte* b, /* in: pointer to 3 bytes where to store */
112
ulint n) /* in: ulint integer to be stored */
115
ut_ad(n <= 0xFFFFFFUL);
117
b[0] = (byte)(n >> 16);
118
b[1] = (byte)(n >> 8);
122
/************************************************************
123
The following function is used to fetch data from 3 consecutive
124
bytes. The most significant byte is at the lowest address. */
129
/* out: ulint integer */
130
byte* b) /* in: pointer to 3 bytes */
133
return( ((ulint)(b[0]) << 16)
134
+ ((ulint)(b[1]) << 8)
139
/***********************************************************
140
The following function is used to store data in four consecutive
141
bytes. We store the most significant byte to the lowest address. */
146
byte* b, /* in: pointer to four bytes where to store */
147
ulint n) /* in: ulint integer to be stored */
151
b[0] = (byte)(n >> 24);
152
b[1] = (byte)(n >> 16);
153
b[2] = (byte)(n >> 8);
157
/************************************************************
158
The following function is used to fetch data from 4 consecutive
159
bytes. The most significant byte is at the lowest address. */
164
/* out: ulint integer */
165
byte* b) /* in: pointer to four bytes */
168
return( ((ulint)(b[0]) << 24)
169
+ ((ulint)(b[1]) << 16)
170
+ ((ulint)(b[2]) << 8)
175
/*************************************************************
176
Writes a ulint in a compressed form where the first byte codes the
177
length of the stored ulint. We look at the most significant bits of
178
the byte. If the most significant bit is zero, it means 1-byte storage,
179
else if the 2nd bit is 0, it means 2-byte storage, else if 3rd is 0,
180
it means 3-byte storage, else if 4th is 0, it means 4-byte storage,
181
else the storage is 5-byte. */
184
mach_write_compressed(
185
/*==================*/
186
/* out: compressed size in bytes */
187
byte* b, /* in: pointer to memory where to store */
188
ulint n) /* in: ulint integer (< 2^32) to be stored */
193
mach_write_to_1(b, n);
195
} else if (n < 0x4000UL) {
196
mach_write_to_2(b, n | 0x8000UL);
198
} else if (n < 0x200000UL) {
199
mach_write_to_3(b, n | 0xC00000UL);
201
} else if (n < 0x10000000UL) {
202
mach_write_to_4(b, n | 0xE0000000UL);
205
mach_write_to_1(b, 0xF0UL);
206
mach_write_to_4(b + 1, n);
211
/*************************************************************
212
Returns the size of a ulint when written in the compressed form. */
215
mach_get_compressed_size(
216
/*=====================*/
217
/* out: compressed size in bytes */
218
ulint n) /* in: ulint integer (< 2^32) to be stored */
222
} else if (n < 0x4000UL) {
224
} else if (n < 0x200000UL) {
226
} else if (n < 0x10000000UL) {
233
/*************************************************************
234
Reads a ulint in a compressed form. */
237
mach_read_compressed(
238
/*=================*/
239
/* out: read integer (< 2^32) */
240
byte* b) /* in: pointer to memory from where to read */
246
flag = mach_read_from_1(b);
250
} else if (flag < 0xC0UL) {
251
return(mach_read_from_2(b) & 0x7FFFUL);
252
} else if (flag < 0xE0UL) {
253
return(mach_read_from_3(b) & 0x3FFFFFUL);
254
} else if (flag < 0xF0UL) {
255
return(mach_read_from_4(b) & 0x1FFFFFFFUL);
257
ut_ad(flag == 0xF0UL);
258
return(mach_read_from_4(b + 1));
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. */
269
byte* b, /* in: pointer to 8 bytes where to store */
270
dulint n) /* in: dulint integer to be stored */
274
mach_write_to_4(b, ut_dulint_get_high(n));
275
mach_write_to_4(b + 4, ut_dulint_get_low(n));
278
/************************************************************
279
The following function is used to fetch data from 8 consecutive
280
bytes. The most significant byte is at the lowest address. */
285
/* out: dulint integer */
286
byte* b) /* in: pointer to 8 bytes */
293
high = mach_read_from_4(b);
294
low = mach_read_from_4(b + 4);
296
return(ut_dulint_create(high, low));
299
/***********************************************************
300
The following function is used to store data in 7 consecutive
301
bytes. We store the most significant byte to the lowest address. */
306
byte* b, /* in: pointer to 7 bytes where to store */
307
dulint n) /* in: dulint integer to be stored */
311
mach_write_to_3(b, ut_dulint_get_high(n));
312
mach_write_to_4(b + 3, ut_dulint_get_low(n));
315
/************************************************************
316
The following function is used to fetch data from 7 consecutive
317
bytes. The most significant byte is at the lowest address. */
322
/* out: dulint integer */
323
byte* b) /* in: pointer to 7 bytes */
330
high = mach_read_from_3(b);
331
low = mach_read_from_4(b + 3);
333
return(ut_dulint_create(high, low));
336
/***********************************************************
337
The following function is used to store data in 6 consecutive
338
bytes. We store the most significant byte to the lowest address. */
343
byte* b, /* in: pointer to 6 bytes where to store */
344
dulint n) /* in: dulint integer to be stored */
348
mach_write_to_2(b, ut_dulint_get_high(n));
349
mach_write_to_4(b + 2, ut_dulint_get_low(n));
352
/************************************************************
353
The following function is used to fetch data from 6 consecutive
354
bytes. The most significant byte is at the lowest address. */
359
/* out: dulint integer */
360
byte* b) /* in: pointer to 7 bytes */
367
high = mach_read_from_2(b);
368
low = mach_read_from_4(b + 2);
370
return(ut_dulint_create(high, low));
373
/*************************************************************
374
Writes a dulint in a compressed form (5..9 bytes). */
377
mach_dulint_write_compressed(
378
/*=========================*/
379
/* out: size in bytes */
380
byte* b, /* in: pointer to memory where to store */
381
dulint n) /* in: dulint integer to be stored */
387
size = mach_write_compressed(b, ut_dulint_get_high(n));
388
mach_write_to_4(b + size, ut_dulint_get_low(n));
393
/*************************************************************
394
Returns the size of a dulint when written in the compressed form. */
397
mach_dulint_get_compressed_size(
398
/*============================*/
399
/* out: compressed size in bytes */
400
dulint n) /* in: dulint integer to be stored */
402
return(4 + mach_get_compressed_size(ut_dulint_get_high(n)));
405
/*************************************************************
406
Reads a dulint in a compressed form. */
409
mach_dulint_read_compressed(
410
/*========================*/
411
/* out: read dulint */
412
byte* b) /* in: pointer to memory from where to read */
420
high = mach_read_compressed(b);
422
size = mach_get_compressed_size(high);
424
low = mach_read_from_4(b + size);
426
return(ut_dulint_create(high, low));
429
/*************************************************************
430
Writes a dulint in a compressed form (1..11 bytes). */
433
mach_dulint_write_much_compressed(
434
/*==============================*/
435
/* out: size in bytes */
436
byte* b, /* in: pointer to memory where to store */
437
dulint n) /* in: dulint integer to be stored */
443
if (ut_dulint_get_high(n) == 0) {
444
return(mach_write_compressed(b, ut_dulint_get_low(n)));
448
size = 1 + mach_write_compressed(b + 1, ut_dulint_get_high(n));
450
size += mach_write_compressed(b + size, ut_dulint_get_low(n));
455
/*************************************************************
456
Returns the size of a dulint when written in the compressed form. */
459
mach_dulint_get_much_compressed_size(
460
/*=================================*/
461
/* out: compressed size in bytes */
462
dulint n) /* in: dulint integer to be stored */
464
if (0 == ut_dulint_get_high(n)) {
465
return(mach_get_compressed_size(ut_dulint_get_low(n)));
468
return(1 + mach_get_compressed_size(ut_dulint_get_high(n))
469
+ mach_get_compressed_size(ut_dulint_get_low(n)));
472
/*************************************************************
473
Reads a dulint in a compressed form. */
476
mach_dulint_read_much_compressed(
477
/*=============================*/
478
/* out: read dulint */
479
byte* b) /* in: pointer to memory from where to read */
487
if (*b != (byte)0xFF) {
491
high = mach_read_compressed(b + 1);
493
size = 1 + mach_get_compressed_size(high);
496
low = mach_read_compressed(b + size);
498
return(ut_dulint_create(high, low));
501
/*************************************************************
502
Reads a double. It is stored in a little-endian format. */
507
/* out: double read */
508
byte* b) /* in: pointer to memory from where to read */
516
for (i = 0; i < sizeof(double); i++) {
517
#ifdef WORDS_BIGENDIAN
518
ptr[sizeof(double) - i - 1] = b[i];
527
/*************************************************************
528
Writes a double. It is stored in a little-endian format. */
533
byte* b, /* in: pointer to memory where to write */
534
double d) /* in: double */
541
for (i = 0; i < sizeof(double); i++) {
542
#ifdef WORDS_BIGENDIAN
543
b[i] = ptr[sizeof(double) - i - 1];
550
/*************************************************************
551
Reads a float. It is stored in a little-endian format. */
556
/* out: float read */
557
byte* b) /* in: pointer to memory from where to read */
565
for (i = 0; i < sizeof(float); i++) {
566
#ifdef WORDS_BIGENDIAN
567
ptr[sizeof(float) - i - 1] = b[i];
576
/*************************************************************
577
Writes a float. It is stored in a little-endian format. */
582
byte* b, /* in: pointer to memory where to write */
583
float d) /* in: float */
590
for (i = 0; i < sizeof(float); i++) {
591
#ifdef WORDS_BIGENDIAN
592
b[i] = ptr[sizeof(float) - i - 1];
599
/*************************************************************
600
Reads a ulint stored in the little-endian format. */
603
mach_read_from_n_little_endian(
604
/*===========================*/
605
/* out: unsigned long int */
606
byte* buf, /* in: from where to read */
607
ulint buf_size) /* in: from how many bytes to read */
612
ut_ad(buf_size <= sizeof(ulint));
615
ptr = buf + buf_size;
632
/*************************************************************
633
Writes a ulint in the little-endian format. */
636
mach_write_to_n_little_endian(
637
/*==========================*/
638
byte* dest, /* in: where to write */
639
ulint dest_size, /* in: into how many bytes to write */
640
ulint n) /* in: unsigned long int to write */
644
ut_ad(dest_size <= sizeof(ulint));
645
ut_ad(dest_size > 0);
647
end = dest + dest_size;
650
*dest = (byte)(n & 0xFF);
664
/*************************************************************
665
Reads a ulint stored in the little-endian format. */
668
mach_read_from_2_little_endian(
669
/*===========================*/
670
/* out: unsigned long int */
671
byte* buf) /* in: from where to read */
673
return((ulint)(*buf) + ((ulint)(*(buf + 1))) * 256);
676
/*************************************************************
677
Writes a ulint in the little-endian format. */
680
mach_write_to_2_little_endian(
681
/*==========================*/
682
byte* dest, /* in: where to write */
683
ulint n) /* in: unsigned long int to write */
685
ut_ad(n < 256 * 256);
687
*dest = (byte)(n & 0xFFUL);
692
*dest = (byte)(n & 0xFFUL);
695
/*************************************************************
696
Convert integral type from storage byte order (big endian) to
702
byte* dest, /* out: where to write */
703
const byte* src, /* in: where to read from */
704
ulint len, /* in: length of src */
705
ibool unsigned_type) /* in: signed or unsigned flag */
707
#ifdef WORDS_BIGENDIAN
708
memcpy(dest, src, len);
710
if (!unsigned_type) {
716
/* Convert integer data from Innobase to a little-endian format,
717
sign bit restored to normal. */
719
for (ptr = dest + len; ptr != dest; ++src) {
724
if (!unsigned_type) {
725
dest[len - 1] ^= 128;