~ubuntu-branches/ubuntu/precise/mysql-5.5/precise-201203300109

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2011-11-08 11:31:13 UTC
  • Revision ID: package-import@ubuntu.com-20111108113113-3ulw01fvi4vn8m25
Tags: upstream-5.5.17
ImportĀ upstreamĀ versionĀ 5.5.17

Show diffs side-by-side

added added

removed removed

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