Skip to content

Commit 926e814

Browse files
committed
support variable offset sizes for real
1 parent b561f67 commit 926e814

File tree

4 files changed

+132
-26
lines changed

4 files changed

+132
-26
lines changed

include/flatcc/flatcc_identifier.h

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,41 @@ static inline void flatbuffers_identifier_from_type_hash(flatbuffers_thash_t typ
6666
out_identifier[0] = (char)(type_hash & 0xff);
6767
type_hash >>= 8;
6868
out_identifier[1] = (char)(type_hash & 0xff);
69+
70+
#if FLATBUFFERS_THASH_WIDTH > 16
6971
type_hash >>= 8;
7072
out_identifier[2] = (char)(type_hash & 0xff);
7173
type_hash >>= 8;
7274
out_identifier[3] = (char)(type_hash & 0xff);
75+
#endif
76+
77+
#if FLATBUFFERS_THASH_WIDTH > 32
78+
type_hash >>= 8;
79+
out_identifier[4] = (char)(type_hash & 0xff);
80+
type_hash >>= 8;
81+
out_identifier[5] = (char)(type_hash & 0xff);
82+
type_hash >>= 8;
83+
out_identifier[6] = (char)(type_hash & 0xff);
84+
type_hash >>= 8;
85+
out_identifier[7] = (char)(type_hash & 0xff);
86+
#endif
7387
}
7488

7589
/* Native integer encoding of file identifier. */
7690
static inline flatbuffers_thash_t flatbuffers_type_hash_from_identifier(const flatbuffers_fid_t identifier)
7791
{
7892
uint8_t *p = (uint8_t *)identifier;
7993

80-
return identifier ?
81-
(uint32_t)p[0] + (((uint32_t)p[1]) << 8) + (((uint32_t)p[2]) << 16) + (((uint32_t)p[3]) << 24) : 0;
94+
return !identifier ? 0 :
95+
96+
#if FLATBUFFERS_THASH_WIDTH == 16
97+
(uint16_t)p[0] + (((uint16_t)p[1]) << 8);
98+
#elif FLATBUFFERS_THASH_WIDTH == 32
99+
(uint32_t)p[0] + (((uint32_t)p[1]) << 8) + (((uint32_t)p[2]) << 16) + (((uint32_t)p[3]) << 24);
100+
#elif FLATBUFFERS_THASH_WIDTH == 64
101+
(uint64_t)p[0] + (((uint64_t)p[1]) << 8) + (((uint64_t)p[2]) << 16) + (((uint64_t)p[3]) << 24) +
102+
(((uint64_t)p[4]) << 32) + (((uint64_t)p[5]) << 40) + (((uint64_t)p[6]) << 48) + (((uint64_t)p[7]) << 56);
103+
#endif
82104
}
83105

84106
/*
@@ -95,10 +117,25 @@ static inline flatbuffers_thash_t flatbuffers_type_hash_from_string(const char *
95117
h += ((flatbuffers_thash_t)p[0]);
96118
if (!p[1]) return h;
97119
h += ((flatbuffers_thash_t)p[1]) << 8;
120+
121+
#if FLATBUFFERS_THASH_WIDTH > 16
98122
if (!p[2]) return h;
99123
h += ((flatbuffers_thash_t)p[2]) << 16;
100-
/* No need to test for termination here. */
124+
if (!p[3]) return h;
101125
h += ((flatbuffers_thash_t)p[3]) << 24;
126+
#endif
127+
128+
#if FLATBUFFERS_THASH_WIDTH > 32
129+
if (!p[4]) return h;
130+
h += ((flatbuffers_thash_t)p[4]) << 32;
131+
if (!p[5]) return h;
132+
h += ((flatbuffers_thash_t)p[5]) << 40;
133+
if (!p[6]) return h;
134+
h += ((flatbuffers_thash_t)p[6]) << 48;
135+
if (!p[7]) return h;
136+
h += ((flatbuffers_thash_t)p[7]) << 56;
137+
#endif
138+
102139
return h;
103140
}
104141

@@ -125,21 +162,31 @@ static inline void flatbuffers_identifier_from_name(const char *name, flatbuffer
125162
* additional information and just complicates matters. Furthermore, the
126163
* unmodified type hash has the benefit that it can seed a child namespace.
127164
*/
128-
static inline uint32_t flatbuffers_disperse_type_hash(flatbuffers_thash_t type_hash)
165+
static inline flatbuffers_thash_t flatbuffers_disperse_type_hash(flatbuffers_thash_t type_hash)
129166
{
167+
flatbuffers_thash_t x = type_hash;
168+
169+
#if FLATBUFFERS_THASH_WIDTH == 32
130170
/* http://stackoverflow.com/a/12996028 */
131-
uint32_t x = type_hash;
132171

133172
x = ((x >> 16) ^ x) * UINT32_C(0x45d9f3b);
134173
x = ((x >> 16) ^ x) * UINT32_C(0x45d9f3b);
135174
x = ((x >> 16) ^ x);
175+
#elif FLATBUFFERS_THASH_WIDTH == 64
176+
/* http://stackoverflow.com/a/12996028 */
177+
178+
x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
179+
x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
180+
x = x ^ (x >> 31);
181+
#endif
182+
136183
return x;
137184
}
138185

139186

140187
/* We have hardcoded assumptions about identifier size. */
141-
static_assert(sizeof(flatbuffers_fid_t) == 4, "unexpected file identifier size");
142-
static_assert(sizeof(flatbuffers_thash_t) == 4, "unexpected type hash size");
188+
//static_assert(sizeof(flatbuffers_fid_t) == 4, "unexpected file identifier size");
189+
//static_assert(sizeof(flatbuffers_thash_t) == 4, "unexpected type hash size");
143190

144191
#ifdef __cplusplus
145192
}

include/flatcc/flatcc_types.h

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ extern "C" {
1111
#include <stdint.h>
1212
#endif
1313

14+
#include "../../config/config.h"
15+
1416
/*
1517
* This should match generated type declaratios in
1618
* `flatbuffers_common_reader.h` (might have different name prefix).
@@ -44,40 +46,80 @@ extern "C" {
4446
#define flatbuffers_thash_t_defined
4547
#define flatbuffers_fid_t_defined
4648

47-
/* uoffset_t is also used for vector and string headers. */
48-
#define FLATBUFFERS_UOFFSET_MAX UINT32_MAX
49-
#define FLATBUFFERS_SOFFSET_MAX INT32_MAX
50-
#define FLATBUFFERS_SOFFSET_MIN INT32_MIN
51-
#define FLATBUFFERS_VOFFSET_MAX UINT16_MAX
52-
#define FLATBUFFERS_UTYPE_MAX UINT8_MAX
53-
/* Well - the max of the underlying type. */
54-
#define FLATBUFFERS_BOOL_MAX UINT8_MAX
55-
#define FLATBUFFERS_THASH_MAX UINT32_MAX
56-
5749
#define FLATBUFFERS_ID_MAX (FLATBUFFERS_VOFFSET_MAX / sizeof(flatbuffers_voffset_t) - 3)
5850
/* Vectors of empty structs can yield div by zero, so we must guard against this. */
5951
#define FLATBUFFERS_COUNT_MAX(elem_size) (FLATBUFFERS_UOFFSET_MAX/((elem_size) == 0 ? 1 : (elem_size)))
6052

61-
#define FLATBUFFERS_UOFFSET_WIDTH 32
62-
#define FLATBUFFERS_COUNT_WIDTH 32
63-
#define FLATBUFFERS_SOFFSET_WIDTH 32
64-
#define FLATBUFFERS_VOFFSET_WIDTH 16
65-
#define FLATBUFFERS_UTYPE_WIDTH 8
66-
#define FLATBUFFERS_BOOL_WIDTH 8
67-
#define FLATBUFFERS_THASH_WIDTH 32
6853

6954
#define FLATBUFFERS_TRUE 1
7055
#define FLATBUFFERS_FALSE 0
7156

7257
#define FLATBUFFERS_PROTOCOL_IS_LE 1
7358
#define FLATBUFFERS_PROTOCOL_IS_BE 0
7459

60+
/* uoffset_t is also used for vector and string headers. */
61+
#if FLATCC_OFFSET_SIZE == 4
7562
typedef uint32_t flatbuffers_uoffset_t;
7663
typedef int32_t flatbuffers_soffset_t;
64+
typedef uint32_t flatbuffers_thash_t;
65+
#define FLATBUFFERS_UOFFSET_MAX UINT32_MAX
66+
#define FLATBUFFERS_SOFFSET_MAX INT32_MAX
67+
#define FLATBUFFERS_SOFFSET_MIN INT32_MIN
68+
#define FLATBUFFERS_THASH_MAX UINT32_MAX
69+
#define FLATBUFFERS_UOFFSET_WIDTH 32
70+
#define FLATBUFFERS_SOFFSET_WIDTH 32
71+
#define FLATBUFFERS_THASH_WIDTH 32
72+
#elif FLATCC_OFFSET_SIZE == 8
73+
typedef uint64_t flatbuffers_uoffset_t;
74+
typedef int64_t flatbuffers_soffset_t;
75+
typedef uint64_t flatbuffers_thash_t;
76+
#define FLATBUFFERS_UOFFSET_MAX UINT64_MAX
77+
#define FLATBUFFERS_SOFFSET_MAX INT64_MAX
78+
#define FLATBUFFERS_SOFFSET_MIN INT64_MIN
79+
#define FLATBUFFERS_THASH_MAX UINT64_MAX
80+
#define FLATBUFFERS_UOFFSET_WIDTH 64
81+
#define FLATBUFFERS_SOFFSET_WIDTH 64
82+
#define FLATBUFFERS_THASH_WIDTH 64
83+
#elif FLATCC_OFFSET_SIZE == 2
84+
typedef uint16_t flatbuffers_uoffset_t;
85+
typedef int16_t flatbuffers_soffset_t;
86+
typedef uint16_t flatbuffers_thash_t;
87+
#define FLATBUFFERS_UOFFSET_MAX UINT16_MAX
88+
#define FLATBUFFERS_SOFFSET_MAX INT16_MAX
89+
#define FLATBUFFERS_SOFFSET_MIN INT16_MIN
90+
#define FLATBUFFERS_THASH_MAX UINT16_MAX
91+
#define FLATBUFFERS_UOFFSET_WIDTH 16
92+
#define FLATBUFFERS_SOFFSET_WIDTH 16
93+
#define FLATBUFFERS_THASH_WIDTH 16
94+
#else
95+
#error FLATCC_OFFSET_SIZE must be defined.
96+
#endif
97+
98+
#if FLATCC_VOFFSET_SIZE == 2
7799
typedef uint16_t flatbuffers_voffset_t;
100+
#define FLATBUFFERS_VOFFSET_MAX UINT16_MAX
101+
#define FLATBUFFERS_VOFFSET_WIDTH 16
102+
#elif FLATCC_VOFFSET_SIZE == 8
103+
typedef uint64_t flatbuffers_voffset_t;
104+
#define FLATBUFFERS_VOFFSET_MAX UINT64_MAX
105+
#define FLATBUFFERS_VOFFSET_WIDTH 64
106+
#elif FLATCC_VOFFSET_SIZE == 4
107+
typedef uint32_t flatbuffers_voffset_t;
108+
#define FLATBUFFERS_VOFFSET_MAX UINT32_MAX
109+
#define FLATBUFFERS_VOFFSET_WIDTH 32
110+
#else
111+
#error FLATCC_VOFFSET_SIZE must be defined.
112+
#endif
113+
114+
#define FLATBUFFERS_UTYPE_MAX UINT8_MAX
115+
#define FLATBUFFERS_UTYPE_WIDTH 8
78116
typedef uint8_t flatbuffers_utype_t;
117+
118+
/* Well - the max of the underlying type. */
119+
#define FLATBUFFERS_BOOL_MAX UINT8_MAX
120+
#define FLATBUFFERS_BOOL_WIDTH 8
79121
typedef uint8_t flatbuffers_bool_t;
80-
typedef uint32_t flatbuffers_thash_t;
122+
81123
/* Public facing type operations. */
82124
typedef flatbuffers_utype_t flatbuffers_union_type_t;
83125

src/compiler/codegen_c.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
#define gen_panic(context, msg) fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg), assert(0), exit(-1)
2020
#endif
2121

22+
#ifndef STRINGIZE
23+
#define STRINGIZE_(x) #x
24+
#define STRINGIZE(x) STRINGIZE_(x)
25+
#endif
2226

2327
static inline void token_name(fb_token_t *t, int *n, const char **s) {
2428
*n = (int)t->len;
@@ -339,6 +343,19 @@ static inline int gen_prologue(fb_output_t *out)
339343
if (out->opts->cgen_pragmas) {
340344
fprintf(out->fp, "#include \"flatcc/flatcc_prologue.h\"\n");
341345
}
346+
347+
fputs(
348+
"#ifndef FLATCC_OFFSET_SIZE \n"
349+
"#define FLATCC_OFFSET_SIZE " STRINGIZE(FLATCC_OFFSET_SIZE) "\n"
350+
"#endif\n",
351+
out->fp);
352+
353+
fputs(
354+
"#ifndef FLATCC_VOFFSET_SIZE \n"
355+
"#define FLATCC_VOFFSET_SIZE " STRINGIZE(FLATCC_VOFFSET_SIZE) "\n"
356+
"#endif\n",
357+
out->fp);
358+
342359
return 0;
343360
}
344361

src/runtime/builder.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ int flatcc_builder_default_alloc(void *alloc_context, iovec_t *b, size_t request
191191
#define table_limit (FLATBUFFERS_VOFFSET_MAX - field_size + 1)
192192
#define data_limit (FLATBUFFERS_UOFFSET_MAX - field_size + 1)
193193

194-
#define set_identifier(id) memcpy(&B->identifier, (id) ? (void *)(id) : (void *)_pad, identifier_size)
194+
#define set_identifier(id) strncpy((char * restrict)&B->identifier, (id) ? (void *)(id) : (void *)_pad, identifier_size)
195195

196196
/* Must also return true when no buffer has been started. */
197197
#define is_top_buffer(B) (B->nest_id == 0)

0 commit comments

Comments
 (0)