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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
#ifndef UBJ_INTERNAL_H
#define UBJ_INTERNAL_H
#include "ubj.h"
#include <stdlib.h>
#include <string.h>
#if _MSC_VER
#define inline __inline
#endif
static const uint8_t UBJI_TYPEC_convert[UBJ_NUM_TYPES] = "\x00ZNTFCSHiUIlLdD[{";
static const int UBJI_TYPE_size[UBJ_NUM_TYPES] =
{ -1, //MIXED
0, //NULLTYPE
0, //NOOP
0, //BOOL_TRUE
0, //BOOL_FALSE
1, //CHAR
sizeof(const char*), //STRING
sizeof(const char*), //high-precision
1, //INT8
1, //UINT8
2, //int16
4, //int32
8, //int64
4, //float32
8, //float64
-1, //array
-1 //object
};
static const size_t UBJR_TYPE_localsize[UBJ_NUM_TYPES] =
{
sizeof(ubjr_dynamic_t), //MIXED
0, //NULLTYPE
0, //NOOP
0, //BOOL_TRUE
0, //BOOL_FALSE
sizeof(ubjr_string_t), //CHAR
sizeof(ubjr_string_t), //STRING
sizeof(ubjr_string_t), //high-precision
sizeof(int8_t), //INT8
sizeof(uint8_t), //UINT8
sizeof(int16_t), //int16
sizeof(int32_t), //int32
sizeof(int64_t), //int64
sizeof(float), //float32
sizeof(double), //float64
sizeof(ubjr_array_t), //array
sizeof(ubjr_object_t) //object
};
static inline void _to_bigendian16(uint8_t* outbuffer, uint16_t input)
{
*outbuffer++ = (input >> 8); // Get top order byte (guaranteed endian-independent since machine registers)
*outbuffer++ = input & 0xFF; // Get bottom order byte
}
static inline void _to_bigendian32(uint8_t* outbuffer, uint32_t input)
{
_to_bigendian16(outbuffer, (uint16_t)(input >> 16)); // Get top order 2 bytes
_to_bigendian16(outbuffer + 2, (uint16_t)(input & 0xFFFF)); // Get bottom order 2 bytes
}
static inline void _to_bigendian64(uint8_t* outbuffer, uint64_t input)
{
_to_bigendian32(outbuffer, (uint32_t)(input >> 32));
_to_bigendian32(outbuffer + 4, (uint32_t)(input & 0xFFFFFFFF));
}
static inline uint8_t _is_bigendian()
{
int i = 1;
char *low = (char*)&i;
return *low ? 0 : 1;
}
#define BUF_BIG_ENDIAN_SWAP(type,func,ptr,num) \
{ \
size_t i;type* d = (type*)ptr; \
for (i = 0; i < num; i++) \
{ \
func((uint8_t*)&d[i], d[i]); \
} \
} \
static inline void buf_endian_swap(uint8_t* buf, size_t sz, size_t n)
{
if (!_is_bigendian())
{
switch (sz)
{
case 1:
case 0:
break;
case 2:
BUF_BIG_ENDIAN_SWAP(uint16_t, _to_bigendian16,buf,n);
break;
case 4:
BUF_BIG_ENDIAN_SWAP(uint32_t, _to_bigendian32,buf,n);
break;
case 8:
BUF_BIG_ENDIAN_SWAP(uint64_t, _to_bigendian64,buf,n);
break;
};
}
}
//warning...null-terminated strings are assumed...when this is not necessarily valid. FIXED: we don't use null-terminated strings in the reader (NOT FIXED...string type is awkward)
static inline ubjr_dynamic_t priv_ubjr_pointer_to_dynamic(UBJ_TYPE typ, const void* dat)
{
ubjr_dynamic_t outdyn;
outdyn.type = typ;
size_t n = 1;
switch (typ)
{
case UBJ_NULLTYPE:
case UBJ_NOOP:
break;
case UBJ_BOOL_TRUE:
case UBJ_BOOL_FALSE:
outdyn.boolean = (typ == UBJ_BOOL_TRUE ? 1 : 0);
break;
case UBJ_HIGH_PRECISION:
case UBJ_STRING:
case UBJ_CHAR://possibly if char allocate, otherwise don't
outdyn.string = *(const ubjr_string_t*)dat;
break;
case UBJ_INT8:
outdyn.integer = *(const int8_t*)dat;
break;
case UBJ_UINT8:
outdyn.integer = *(const uint8_t*)dat;
break;
case UBJ_INT16:
outdyn.integer = *(const int16_t*)dat;
break;
case UBJ_INT32:
outdyn.integer = *(const int32_t*)dat;
break;
case UBJ_INT64:
outdyn.integer = *(const int64_t*)dat;
break;
case UBJ_FLOAT32:
outdyn.real = *(const float*)dat;
break;
case UBJ_FLOAT64:
outdyn.real = *(const double*)dat;
break;
case UBJ_ARRAY:
outdyn.container_array = *(const ubjr_array_t*)dat;
break;
case UBJ_OBJECT:
outdyn.container_object = *(const ubjr_object_t*)dat;
break;
case UBJ_MIXED:
outdyn = *(const ubjr_dynamic_t*)dat;
};
return outdyn;
}
#endif
|