diff --git a/src/l2/core/glb_file.h b/src/l2/core/glb_file.h index e4a1079..f4dd274 100644 --- a/src/l2/core/glb_file.h +++ b/src/l2/core/glb_file.h @@ -7,6 +7,7 @@ /* Points to some string (BIN segment) + contains decoded json object */ typedef struct { + U32 version; Json gltf; /* If length is 0, BIN segment is absent */ SpanU8 bin_segment; @@ -26,6 +27,7 @@ int glb_file_get_segments(SpanU8 file, GLBFileSegments* ret){ if (*(const U32*)file.data != 0x46546C67) { return 2; } + U32 version = *(const U32*)(file.data + 4); /* Nobody cares about version */ if (*(const U32*)(file.data + 8) != file.len) { return 3; @@ -54,17 +56,18 @@ int glb_file_get_segments(SpanU8 file, GLBFileSegments* ret){ } bin_segment = cur_segment; } + cur += 8 + chunk_length; + } + if (json_segment.len == 0) { + /* Illegal, no json segment */ + return 8; } - // if (json_segment.len == 0) { - // /* Illegal, no json segment */ - // return 8; - // } OptionJson parsed_json = json_decode(json_segment, 15); if (parsed_json.variant == Option_None) { return 9; } /* Everything is correct */ - *ret = (GLBFileSegments){.gltf = parsed_json.some, .bin_segment = bin_segment}; + *ret = (GLBFileSegments){.version = version, .gltf = parsed_json.some, .bin_segment = bin_segment}; return 0; } diff --git a/src/l2/core/json_encoded.h b/src/l2/core/json_encoded.h index e657715..97e340e 100644 --- a/src/l2/core/json_encoded.h +++ b/src/l2/core/json_encoded.h @@ -127,7 +127,7 @@ int json_decoding_parse_string(SpanU8* rem, VecU8* ret_str){ } else if (ch == 'f') { VecU8_append(&res, '\f'); } else if (ch == 'n') { - VecU8_append(&res, '\b'); + VecU8_append(&res, '\n'); } else if (ch == 'r') { VecU8_append(&res, '\r'); } else if (ch == 't') { @@ -173,14 +173,16 @@ OptionJson json_decoding_h_no_spaces(SpanU8* rem, U32 depth_rem){ if (depth_rem == 0) { return None_Json(); } - float fl_value; - int fl_code = SpanU8_read_float(rem, &fl_value); - if (fl_code == 0) - return Some_Json(Json_from_float(fl_value)); S64 int_value; int int_code = SpanU8_read_S64(rem, &int_value); if (int_code == 0) return Some_Json(Json_from_int(int_value)); + + float fl_value; + int fl_code = SpanU8_read_float(rem, &fl_value); + if (fl_code == 0) + return Some_Json(Json_from_float(fl_value)); + bool false_code = SpanU8_parsing_try_read_prefix(rem, cstr("false")); if (false_code) return Some_Json(Json_False); @@ -234,30 +236,31 @@ OptionJson json_decoding_h_no_spaces(SpanU8* rem, U32 depth_rem){ RBTree_MapVecU8ToJson_drop(dict); return None_Json(); } - VecU8 key; - int key_code = json_decoding_parse_string(rem, &key); - if (key_code) { - RBTree_MapVecU8ToJson_drop(dict); - return None_Json(); - } - SpanU8_parsing_skip_spaces(rem); - if (!SpanU8_parsing_try_read_char(rem, ':')) { - RBTree_MapVecU8ToJson_drop(dict); - VecU8_drop(key); - return None_Json(); - } - OptionJson x = json_decoding_h(rem, depth_rem - 1); - if (x.variant == Option_None) { - RBTree_MapVecU8ToJson_drop(dict); - VecU8_drop(key); - return None_Json(); - } - bool iret = RBTree_MapVecU8ToJson_insert(&dict, key, x.some); - if (!iret) { - /* Two elements of dictionary share the same key. Very illegal */ - RBTree_MapVecU8ToJson_drop(dict); - return None_Json(); - } + } + SpanU8_parsing_skip_spaces(rem); + VecU8 key; + int key_code = json_decoding_parse_string(rem, &key); + if (key_code) { + RBTree_MapVecU8ToJson_drop(dict); + return None_Json(); + } + SpanU8_parsing_skip_spaces(rem); + if (!SpanU8_parsing_try_read_char(rem, ':')) { + RBTree_MapVecU8ToJson_drop(dict); + VecU8_drop(key); + return None_Json(); + } + OptionJson x = json_decoding_h(rem, depth_rem - 1); + if (x.variant == Option_None) { + RBTree_MapVecU8ToJson_drop(dict); + VecU8_drop(key); + return None_Json(); + } + bool iret = RBTree_MapVecU8ToJson_insert(&dict, key, x.some); + if (!iret) { + /* Two elements of dictionary share the same key. Very illegal */ + RBTree_MapVecU8ToJson_drop(dict); + return None_Json(); } } } diff --git a/src/l2/tests/t_parsing.c b/src/l2/tests/t_parsing.c index 542b3df..f799375 100644 --- a/src/l2/tests/t_parsing.c +++ b/src/l2/tests/t_parsing.c @@ -165,13 +165,17 @@ void tt15(){ test_s64_reading_with_good_inp(cstr("0-"), 0, 1); } +void test_float_near(float right_val, float val, float eps){ + check((right_val >= +1e60 && val >= +1e60) || (right_val <= -1e60 && val <= -1e60) || fabsf(right_val - val) < eps); +} + void test_float_reading_with_good_inp(SpanU8 str, float right_val, float eps, U64 lo){ SpanU8 rem = str; float val; int c = SpanU8_read_float(&rem, &val); check(c == 0); check(rem.data == str.data + str.len - lo && rem.len == lo); - check((right_val >= +1e60 && val >= +1e60) || (right_val <= -1e60 && val <= -1e60) || fabsf(right_val - val) < eps); + test_float_near(right_val, val, eps); } void tt16(){ @@ -321,18 +325,69 @@ void test_json_equal(const Json* a, const Json* b){ if (a->variant == Json_integer) { check(a->integer == b->integer); } else if (a->variant == Json_float) { - check(fabsf(a->float_num - b->float_num)) + test_float_near(a->float_num, b->float_num, 0.01f); } else if (a->variant == Json_str) { check(VecU8_equal_VecU8(&a->str, &b->str)); + } else if (a->variant == Json_arr) { + const VecJson* A = &a->arr; + const VecJson* B = &b->arr; + check(A->len == B->len); + for (size_t i = 0; i < A->len; i++) { + test_json_equal(&A->buf[i], &B->buf[i]); + } + } else if (a->variant == Json_dict) { + const json_dictionary_t* A = &a->dict; + const json_dictionary_t* B = &b->dict; + RBTreeNode_KVPVecU8ToJson* i_a = RBTree_MapVecU8ToJson_find_min(A); + RBTreeNode_KVPVecU8ToJson* i_b = RBTree_MapVecU8ToJson_find_min(B); + while (i_a != NULL && i_b != NULL) { + check(VecU8_equal_VecU8(&i_a->key, &i_b->key)); + test_json_equal(&i_a->value, &i_b->value); + i_a = RBTree_MapVecU8ToJson_find_next(A, i_a); + i_b = RBTree_MapVecU8ToJson_find_next(B, i_b); + } + check(i_a == NULL); + check(i_b == NULL); } } void test_json_decoding_ok(const char* str_lit, Json right_ans){ - + OptionJson my_ans = json_decode(SpanU8_from_cstr(str_lit), 10); + check(my_ans.variant == Option_Some); + test_json_equal(&my_ans.some, &right_ans); + Json_drop(my_ans.some); + Json_drop(right_ans); } void tt27(){ + test_json_decoding_ok("true", Json_True); + test_json_decoding_ok("\n\n1233", Json_from_int(1233)); + test_json_decoding_ok("false\r \t ", Json_False); + test_json_decoding_ok(" none", Json_None); + test_json_decoding_ok("999999999999999999999999999999999999999", Json_from_float(1e100)); + test_json_decoding_ok(" [ \t\r\r\n ]", Json_from_VecJson(VecJson_new())); + test_json_decoding_ok(" { } ", Json_from_MapVecU8ToJson(RBTree_MapVecU8ToJson_new())); + test_json_decoding_ok(" \"7\" ", Json_from_SpanU8(cstr("7"))); + test_json_decoding_ok(" \"XXX\" ", Json_from_SpanU8(cstr("XXX"))); + { + VecJson x = VecJson_new(); + VecJson_append(&x, Json_from_int(12)); + VecJson_append(&x, Json_from_int(23)); + VecJson_append(&x, Json_from_int(34)); + test_json_decoding_ok("[ 12,23 , \n 34 ]", Json_from_VecJson(x)); + } + { + json_dictionary_t x = RBTree_MapVecU8ToJson_new(); + RBTree_MapVecU8ToJson_insert(&x, vcstr("XXX"), Json_from_int(9990)); + test_json_decoding_ok(" { \"XXX\" : 9990 }", Json_from_MapVecU8ToJson(x)); + } +} +void tt28(){ + json_dictionary_t x = RBTree_MapVecU8ToJson_new(); + RBTree_MapVecU8ToJson_insert(&x, vcstr("9\u0449AB-"), Json_from_bool(false)); + RBTree_MapVecU8ToJson_insert(&x, vcstr("9\u0449A"), Json_from_int(999)); + test_json_decoding_ok(" { \"9\u0449A\" : 999 , \"9\\u0449AB-\" : false }", Json_from_MapVecU8ToJson(x)); } void test_json_decoding_with_ill_formed_inp(const char* str_lit){ @@ -340,11 +395,14 @@ void test_json_decoding_with_ill_formed_inp(const char* str_lit){ check(res.variant == Option_None); } -void tt28(){ +void tt29(){ + test_json_decoding_with_ill_formed_inp("{"); + test_json_decoding_with_ill_formed_inp("{\"A\": 12, \"A\": 12}"); + test_json_decoding_with_ill_formed_inp("["); test_json_decoding_with_ill_formed_inp("123e2222222222222222222222222"); - test_json_decoding_with_ill_formed_inp("999999999999999999999999999999999999999"); test_json_decoding_with_ill_formed_inp("\"666"); test_json_decoding_with_ill_formed_inp("{{{}}"); + test_json_decoding_with_ill_formed_inp("{\"a\": 2 \"b\": 12}"); test_json_decoding_with_ill_formed_inp("f"); test_json_decoding_with_ill_formed_inp("tru"); test_json_decoding_with_ill_formed_inp("none3"); @@ -356,6 +414,7 @@ void tt28(){ int main(){ tt1(); tt2(); tt3(); tt4(); tt5(); tt6(); tt7(); tt8(); tt9(); tt10(); tt11(); tt12(); tt13(); tt14(); tt15(); tt16(); tt17(); tt18(); tt19(); - tt20(); tt21(); tt22(); tt23(); tt24(); tt25(); tt26(); + tt20(); tt21(); tt22(); tt23(); tt24(); tt25(); tt26(); tt27(); + tt28(); tt29(); return 0; }