source: branches/stable/ARBDB/ad_io_inline.h

Last change on this file was 15529, checked in by westram, 7 years ago
File size: 3.1 KB
Line 
1// ============================================================= //
2//                                                               //
3//   File      : ad_io_inline.h                                  //
4//   Purpose   :                                                 //
5//                                                               //
6//   Coded by Ralf Westram (coder@reallysoft.de) in April 2012   //
7//   Institute of Microbiology (Technical University Munich)     //
8//   http://www.arb-home.de/                                     //
9//                                                               //
10// ============================================================= //
11
12#ifndef AD_IO_INLINE_H
13#define AD_IO_INLINE_H
14
15#ifndef STATIC_ASSERT_H
16#include <static_assert.h>
17#endif
18
19CONSTEXPR_INLINE_Cxx14 void swap(unsigned char& c1, unsigned char& c2) { unsigned char c = c1; c1 = c2; c2 = c; }
20
21inline uint32_t reverse_byteorder(uint32_t val) {
22    union {
23        uint32_t      as_uint32;
24        unsigned char as_char[4];
25    } data;
26    STATIC_ASSERT(sizeof(data)           == 4);
27    STATIC_ASSERT(sizeof(data.as_uint32) == 4);
28
29    data.as_uint32 = val;
30
31    swap(data.as_char[0], data.as_char[3]);
32    swap(data.as_char[1], data.as_char[2]);
33
34    return data.as_uint32;
35}
36
37inline void gb_write_out_uint32(uint32_t data, FILE *out) {
38    // opposite of gb_read_in_uint32
39    ASSERT_RESULT(size_t, 1, fwrite(&data, sizeof(data), 1, out));
40}
41
42inline uint32_t gb_read_in_uint32(FILE *in, bool reversed) {
43    // opposite of gb_write_out_uint32
44    uint32_t val;
45    ASSERT_RESULT(size_t, 1, fread(&val, sizeof(val), 1, in));
46    return reversed ? reverse_byteorder(val) : val;
47}
48
49inline void gb_put_number(long b0, FILE *out) {
50    // opposite of gb_get_number
51
52    if (b0 < 0) {
53        // if this happens, we are in 32/64bit-hell
54        // if it never fails, gb_put_number/gb_get_number should better work with uint32_t
55        // see also ad_load.cxx@bit-hell
56        GBK_terminate("32/64bit incompatibility detected in DB-engine, please inform devel@arb-home.de");
57    }
58   
59    typedef unsigned char uc;
60    if (b0 >= 0x80) {
61        long b1 = b0>>8;
62        if (b1 >= 0x40) {
63            long b2 = b1>>8;
64            if (b2 >= 0x20) {
65                long b3 = b2>>8;
66                if (b3 >= 0x10) putc(0xf0, out);
67                else b3 |= 0xE0;
68                putc(uc(b3), out);
69            }
70            else b2 |= 0xC0;
71            putc(uc(b2), out);
72        }
73        else b1 |= 0x80;
74        putc(uc(b1), out);
75    }
76    putc(uc(b0), out);
77}
78
79inline long gb_get_number(FILE *in) {
80    // opposite of gb_put_number
81    unsigned int b0  = getc(in);
82    unsigned int RES = b0;
83    if (b0 & 0x80) {
84        RES = getc(in);
85        if (b0 & 0x40) {
86            RES = (RES << 8) | getc(in);
87            if (b0 & 0x20) {
88                RES = (RES << 8) | getc(in);
89                if (b0 & 0x10) RES = (RES << 8) | getc(in);
90                else RES |= (b0 & 0x0f) << 24;
91            }
92            else RES |= (b0 & 0x1f) << 16;
93        }
94        else RES |= (b0 & 0x3f) << 8;
95    }
96    return RES;
97}
98
99
100#else
101#error ad_io_inline.h included twice
102#endif // AD_IO_INLINE_H
Note: See TracBrowser for help on using the repository browser.