Skip to content

Commit a540dcc

Browse files
committed
#608 support NaN and Inf values in serializers
1 parent 1d8e6c5 commit a540dcc

File tree

14 files changed

+400
-19
lines changed

14 files changed

+400
-19
lines changed

flecs.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11077,6 +11077,7 @@ void flecs_bitset_swap(
1107711077
}
1107811078

1107911079
#include <stdio.h>
11080+
#include <math.h>
1108011081

1108111082
/**
1108211083
* stm32tpl -- STM32 C++ Template Peripheral Library
@@ -11105,14 +11106,34 @@ static
1110511106
int ecs_strbuf_ftoa(
1110611107
ecs_strbuf_t *out,
1110711108
double f,
11108-
int precision)
11109+
int precision,
11110+
char nan_delim)
1110911111
{
1111011112
char buf[64];
1111111113
char * ptr = buf;
1111211114
char * p1;
1111311115
char c;
1111411116
int64_t intPart;
1111511117

11118+
if (isnan(f)) {
11119+
if (nan_delim) {
11120+
ecs_strbuf_appendch(out, nan_delim);
11121+
ecs_strbuf_appendstr(out, "nan");
11122+
return ecs_strbuf_appendch(out, nan_delim);
11123+
} else {
11124+
return ecs_strbuf_appendstr(out, "nan");
11125+
}
11126+
}
11127+
if (isinf(f)) {
11128+
if (nan_delim) {
11129+
ecs_strbuf_appendch(out, nan_delim);
11130+
ecs_strbuf_appendstr(out, "inf");
11131+
return ecs_strbuf_appendch(out, nan_delim);
11132+
} else {
11133+
return ecs_strbuf_appendstr(out, "inf");
11134+
}
11135+
}
11136+
1111611137
if (precision > MAX_PRECISION) {
1111711138
precision = MAX_PRECISION;
1111811139
}
@@ -11469,10 +11490,11 @@ bool ecs_strbuf_appendch(
1146911490

1147011491
bool ecs_strbuf_appendflt(
1147111492
ecs_strbuf_t *b,
11472-
double flt)
11493+
double flt,
11494+
char nan_delim)
1147311495
{
1147411496
ecs_assert(b != NULL, ECS_INVALID_PARAMETER, NULL);
11475-
return ecs_strbuf_ftoa(b, flt, 2);
11497+
return ecs_strbuf_ftoa(b, flt, 2, nan_delim);
1147611498
}
1147711499

1147811500
bool ecs_strbuf_appendstr_zerocpy(
@@ -23089,10 +23111,10 @@ int expr_ser_primitive(
2308923111
ecs_strbuf_append(str, "%lld", *(int64_t*)base);
2309023112
break;
2309123113
case EcsF32:
23092-
ecs_strbuf_appendflt(str, (double)*(float*)base);
23114+
ecs_strbuf_appendflt(str, (double)*(float*)base, 0);
2309323115
break;
2309423116
case EcsF64:
23095-
ecs_strbuf_appendflt(str, *(double*)base);
23117+
ecs_strbuf_appendflt(str, *(double*)base, 0);
2309623118
break;
2309723119
case EcsIPtr:
2309823120
ecs_strbuf_append(str, "%i", *(intptr_t*)base);
@@ -25328,7 +25350,7 @@ void json_number(
2532825350
ecs_strbuf_t *buf,
2532925351
double value)
2533025352
{
25331-
ecs_strbuf_appendflt(buf, value);
25353+
ecs_strbuf_appendflt(buf, value, '"');
2533225354
}
2533325355

2533425356
void json_true(
@@ -25621,6 +25643,14 @@ int json_ser_type_op(
2562125643
/* Should not be parsed as single op */
2562225644
ecs_throw(ECS_INVALID_PARAMETER, NULL);
2562325645
break;
25646+
case EcsOpF32:
25647+
ecs_strbuf_appendflt(str,
25648+
(ecs_f64_t)*(ecs_f32_t*)ECS_OFFSET(ptr, op->offset), '"');
25649+
break;
25650+
case EcsOpF64:
25651+
ecs_strbuf_appendflt(str,
25652+
*(ecs_f64_t*)ECS_OFFSET(ptr, op->offset), '"');
25653+
break;
2562425654
case EcsOpEnum:
2562525655
if (json_ser_enum(world, op, ECS_OFFSET(ptr, op->offset), str)) {
2562625656
goto error;

flecs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,8 @@ bool ecs_strbuf_appendch(
17101710
FLECS_API
17111711
bool ecs_strbuf_appendflt(
17121712
ecs_strbuf_t *buffer,
1713-
double v);
1713+
double v,
1714+
char nan_delim);
17141715

17151716
/* Append source buffer to destination buffer.
17161717
* Returns false when max is reached, true when there is still space */

include/flecs/private/strbuf.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ bool ecs_strbuf_appendch(
115115
FLECS_API
116116
bool ecs_strbuf_appendflt(
117117
ecs_strbuf_t *buffer,
118-
double v);
118+
double v,
119+
char nan_delim);
119120

120121
/* Append source buffer to destination buffer.
121122
* Returns false when max is reached, true when there is still space */

src/addons/expr/serialize.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ int expr_ser_primitive(
8585
ecs_strbuf_append(str, "%lld", *(int64_t*)base);
8686
break;
8787
case EcsF32:
88-
ecs_strbuf_appendflt(str, (double)*(float*)base);
88+
ecs_strbuf_appendflt(str, (double)*(float*)base, 0);
8989
break;
9090
case EcsF64:
91-
ecs_strbuf_appendflt(str, *(double*)base);
91+
ecs_strbuf_appendflt(str, *(double*)base, 0);
9292
break;
9393
case EcsIPtr:
9494
ecs_strbuf_append(str, "%i", *(intptr_t*)base);

src/addons/json/json.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void json_number(
1919
ecs_strbuf_t *buf,
2020
double value)
2121
{
22-
ecs_strbuf_appendflt(buf, value);
22+
ecs_strbuf_appendflt(buf, value, '"');
2323
}
2424

2525
void json_true(

src/addons/json/serialize.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,14 @@ int json_ser_type_op(
207207
/* Should not be parsed as single op */
208208
ecs_throw(ECS_INVALID_PARAMETER, NULL);
209209
break;
210+
case EcsOpF32:
211+
ecs_strbuf_appendflt(str,
212+
(ecs_f64_t)*(ecs_f32_t*)ECS_OFFSET(ptr, op->offset), '"');
213+
break;
214+
case EcsOpF64:
215+
ecs_strbuf_appendflt(str,
216+
*(ecs_f64_t*)ECS_OFFSET(ptr, op->offset), '"');
217+
break;
210218
case EcsOpEnum:
211219
if (json_ser_enum(world, op, ECS_OFFSET(ptr, op->offset), str)) {
212220
goto error;

src/datastructures/strbuf.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "../private_api.h"
22
#include <stdio.h>
3+
#include <math.h>
34

45
/**
56
* stm32tpl -- STM32 C++ Template Peripheral Library
@@ -28,14 +29,34 @@ static
2829
int ecs_strbuf_ftoa(
2930
ecs_strbuf_t *out,
3031
double f,
31-
int precision)
32+
int precision,
33+
char nan_delim)
3234
{
3335
char buf[64];
3436
char * ptr = buf;
3537
char * p1;
3638
char c;
3739
int64_t intPart;
3840

41+
if (isnan(f)) {
42+
if (nan_delim) {
43+
ecs_strbuf_appendch(out, nan_delim);
44+
ecs_strbuf_appendstr(out, "nan");
45+
return ecs_strbuf_appendch(out, nan_delim);
46+
} else {
47+
return ecs_strbuf_appendstr(out, "nan");
48+
}
49+
}
50+
if (isinf(f)) {
51+
if (nan_delim) {
52+
ecs_strbuf_appendch(out, nan_delim);
53+
ecs_strbuf_appendstr(out, "inf");
54+
return ecs_strbuf_appendch(out, nan_delim);
55+
} else {
56+
return ecs_strbuf_appendstr(out, "inf");
57+
}
58+
}
59+
3960
if (precision > MAX_PRECISION) {
4061
precision = MAX_PRECISION;
4162
}
@@ -392,10 +413,11 @@ bool ecs_strbuf_appendch(
392413

393414
bool ecs_strbuf_appendflt(
394415
ecs_strbuf_t *b,
395-
double flt)
416+
double flt,
417+
char nan_delim)
396418
{
397419
ecs_assert(b != NULL, ECS_INVALID_PARAMETER, NULL);
398-
return ecs_strbuf_ftoa(b, flt, 2);
420+
return ecs_strbuf_ftoa(b, flt, 2, nan_delim);
399421
}
400422

401423
bool ecs_strbuf_appendstr_zerocpy(

test/collections/project.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,11 @@
121121
"append_511_chars",
122122
"append_512_chars",
123123
"append_513_chars",
124-
"append_flt"
124+
"append_flt",
125+
"append_nan",
126+
"append_inf",
127+
"append_nan_delim",
128+
"append_inf_delim"
125129
]
126130
}]
127131
}

test/collections/src/Strbuf.c

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <collections.h>
2+
#include <math.h>
23

34
void Strbuf_setup() {
45
ecs_os_set_api_defaults();
@@ -234,10 +235,72 @@ void Strbuf_append_513_chars() {
234235

235236
void Strbuf_append_flt() {
236237
ecs_strbuf_t b = ECS_STRBUF_INIT;
237-
ecs_strbuf_appendflt(&b, 10.5);
238+
ecs_strbuf_appendflt(&b, 10.5, 0);
238239

239240
char *str = ecs_strbuf_get(&b);
240241
test_assert(str != NULL);
241242
test_str(str, "10.50");
242243
ecs_os_free(str);
243244
}
245+
246+
void Strbuf_append_nan() {
247+
ecs_strbuf_t b = ECS_STRBUF_INIT;
248+
ecs_strbuf_appendflt(&b, NAN, 0);
249+
250+
char *str = ecs_strbuf_get(&b);
251+
test_assert(str != NULL);
252+
test_str(str, "nan");
253+
ecs_os_free(str);
254+
}
255+
256+
void Strbuf_append_inf() {
257+
{
258+
ecs_strbuf_t b = ECS_STRBUF_INIT;
259+
ecs_strbuf_appendflt(&b, INFINITY, 0);
260+
261+
char *str = ecs_strbuf_get(&b);
262+
test_assert(str != NULL);
263+
test_str(str, "inf");
264+
ecs_os_free(str);
265+
}
266+
{
267+
ecs_strbuf_t b = ECS_STRBUF_INIT;
268+
ecs_strbuf_appendflt(&b, -INFINITY, 0);
269+
270+
char *str = ecs_strbuf_get(&b);
271+
test_assert(str != NULL);
272+
test_str(str, "inf");
273+
ecs_os_free(str);
274+
}
275+
}
276+
277+
void Strbuf_append_nan_delim() {
278+
ecs_strbuf_t b = ECS_STRBUF_INIT;
279+
ecs_strbuf_appendflt(&b, NAN, '"');
280+
281+
char *str = ecs_strbuf_get(&b);
282+
test_assert(str != NULL);
283+
test_str(str, "\"nan\"");
284+
ecs_os_free(str);
285+
}
286+
287+
void Strbuf_append_inf_delim() {
288+
{
289+
ecs_strbuf_t b = ECS_STRBUF_INIT;
290+
ecs_strbuf_appendflt(&b, INFINITY, '"');
291+
292+
char *str = ecs_strbuf_get(&b);
293+
test_assert(str != NULL);
294+
test_str(str, "\"inf\"");
295+
ecs_os_free(str);
296+
}
297+
{
298+
ecs_strbuf_t b = ECS_STRBUF_INIT;
299+
ecs_strbuf_appendflt(&b, -INFINITY, '"');
300+
301+
char *str = ecs_strbuf_get(&b);
302+
test_assert(str != NULL);
303+
test_str(str, "\"inf\"");
304+
ecs_os_free(str);
305+
}
306+
}

test/collections/src/main.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ void Strbuf_append_511_chars(void);
111111
void Strbuf_append_512_chars(void);
112112
void Strbuf_append_513_chars(void);
113113
void Strbuf_append_flt(void);
114+
void Strbuf_append_nan(void);
115+
void Strbuf_append_inf(void);
116+
void Strbuf_append_nan_delim(void);
117+
void Strbuf_append_inf_delim(void);
114118

115119
bake_test_case Vector_testcases[] = {
116120
{
@@ -489,6 +493,22 @@ bake_test_case Strbuf_testcases[] = {
489493
{
490494
"append_flt",
491495
Strbuf_append_flt
496+
},
497+
{
498+
"append_nan",
499+
Strbuf_append_nan
500+
},
501+
{
502+
"append_inf",
503+
Strbuf_append_inf
504+
},
505+
{
506+
"append_nan_delim",
507+
Strbuf_append_nan_delim
508+
},
509+
{
510+
"append_inf_delim",
511+
Strbuf_append_inf_delim
492512
}
493513
};
494514

@@ -518,7 +538,7 @@ static bake_test_suite suites[] = {
518538
"Strbuf",
519539
Strbuf_setup,
520540
NULL,
521-
19,
541+
23,
522542
Strbuf_testcases
523543
}
524544
};

0 commit comments

Comments
 (0)