ARB
ad_io_inline.h
Go to the documentation of this file.
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 
19 CONSTEXPR_INLINE_Cxx14 void swap(unsigned char& c1, unsigned char& c2) { unsigned char c = c1; c1 = c2; c2 = c; }
20 
21 inline 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 
37 inline 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 
42 inline 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 
49 inline 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 
79 inline 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
void gb_put_number(long b0, FILE *out)
Definition: ad_io_inline.h:49
long gb_get_number(FILE *in)
Definition: ad_io_inline.h:79
#define ASSERT_RESULT(Type, Expected, Expr)
Definition: arb_assert.h:336
void gb_write_out_uint32(uint32_t data, FILE *out)
Definition: ad_io_inline.h:37
#define CONSTEXPR_INLINE_Cxx14
Definition: cxxforward.h:55
uint32_t reverse_byteorder(uint32_t val)
Definition: ad_io_inline.h:21
void GBK_terminate(const char *error) __ATTR__NORETURN
Definition: arb_msg.cxx:463
CONSTEXPR_INLINE_Cxx14 void swap(unsigned char &c1, unsigned char &c2)
Definition: ad_io_inline.h:19
#define STATIC_ASSERT(const_expression)
Definition: static_assert.h:36
uint32_t gb_read_in_uint32(FILE *in, bool reversed)
Definition: ad_io_inline.h:42