~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

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