File: ad_io_inline.h

package info (click to toggle)
arb 6.0.2-1%2Bdeb8u1
  • links: PTS, VCS
  • area: non-free
  • in suites: jessie
  • size: 65,916 kB
  • ctags: 53,258
  • sloc: ansic: 394,903; cpp: 250,252; makefile: 19,620; sh: 15,878; perl: 10,461; fortran: 6,019; ruby: 683; xml: 503; python: 53; awk: 32
file content (102 lines) | stat: -rw-r--r-- 3,176 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// ============================================================= //
//                                                               //
//   File      : ad_io_inline.h                                  //
//   Purpose   :                                                 //
//                                                               //
//   Coded by Ralf Westram (coder@reallysoft.de) in April 2012   //
//   Institute of Microbiology (Technical University Munich)     //
//   http://www.arb-home.de/                                     //
//                                                               //
// ============================================================= //

#ifndef AD_IO_INLINE_H
#define AD_IO_INLINE_H

#ifndef STATIC_ASSERT_H
#include <static_assert.h>
#endif

inline void swap(unsigned char& c1, unsigned char& c2) { unsigned char c = c1; c1 = c2; c2 = c; }

inline uint32_t reverse_byteorder(uint32_t val) {
    union {
        uint32_t      as_uint32;
        unsigned char as_char[4];
    } data;
    STATIC_ASSERT(sizeof(data)           == 4);
    STATIC_ASSERT(sizeof(data.as_uint32) == 4);

    data.as_uint32 = val;

    swap(data.as_char[0], data.as_char[3]);
    swap(data.as_char[1], data.as_char[2]);

    return data.as_uint32;
}

inline void gb_write_out_uint32(uint32_t data, FILE *out) {
    // opposite of gb_read_in_uint32
    ASSERT_RESULT(size_t, 1, fwrite(&data, sizeof(data), 1, out));
}

inline uint32_t gb_read_in_uint32(FILE *in, bool reversed) {
    // opposite of gb_write_out_uint32
    uint32_t val;
    ASSERT_RESULT(size_t, 1, fread(&val, sizeof(val), 1, in));
    return reversed ? reverse_byteorder(val) : val;
}

inline void gb_put_number(long b0, FILE *out) {
    // opposite of gb_get_number

    if (b0 < 0) {
        // if this happens, we are in 32/64bit-hell
        // if it never fails, gb_put_number/gb_get_number should better work with uint32_t
        // see also ad_load.cxx@bit-hell
        GBK_terminate("32/64bit incompatibility detected in DB-engine, please inform devel@arb-home.de");
    }
    
    typedef unsigned char uc;
    if (b0 >= 0x80) {
        long b1 = b0>>8;
        if (b1 >= 0x40) {
            long b2 = b1>>8;
            if (b2 >= 0x20) {
                long b3 = b2>>8;
                if (b3 >= 0x10) putc(0xf0, out);
                else b3 |= 0xE0;
                putc(uc(b3), out);
            }
            else b2 |= 0xC0;
            putc(uc(b2), out);
        }
        else b1 |= 0x80;
        putc(uc(b1), out);
    }
    putc(uc(b0), out);
}

inline long gb_get_number(FILE *in) {
    // opposite of gb_put_number
    unsigned int b0  = getc(in);
    unsigned int RES = b0;
    if (b0 & 0x80) {
        RES = getc(in);
        if (b0 & 0x40) {
            RES = (RES << 8) | getc(in);
            if (b0 & 0x20) {
                RES = (RES << 8) | getc(in);
                if (b0 & 0x10) RES = (RES << 8) | getc(in);
                else RES |= (b0 & 0x0f) << 24;
            }
            else RES |= (b0 & 0x1f) << 16;
        }
        else RES |= (b0 & 0x3f) << 8;
    }
    return RES;
}


#else
#error ad_io_inline.h included twice
#endif // AD_IO_INLINE_H