~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/include/mach0data.ic

Tags: innodb-plugin-1.0.1
Imported 1.0.1 with clean - with no changes.

Show diffs side-by-side

added added

removed removed

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