void AddWrittenPtr( const void* ptr, uintptr_t pos ) { DL_ASSERT( num_written_ptrs < (int)DL_ARRAY_LENGTH(written_ptrs) ); written_ptrs[num_written_ptrs].ptr = ptr; written_ptrs[num_written_ptrs].pos = pos; ++num_written_ptrs; }
TYPED_TEST(DLBase, array_struct_with_ptr_holder) { Pods2 p1, p2, p3; p1.Int1 = 1; p1.Int2 = 2; p2.Int1 = 3; p2.Int2 = 4; p3.Int1 = 5; p3.Int2 = 6; // testing array of pointer-type PtrHolder arr[] = { { &p1 }, { &p2 }, { &p2 }, { &p3 } }; PtrArray original = { { arr, DL_ARRAY_LENGTH( arr ) } }; PtrArray loaded[16]; this->do_the_round_about( PtrArray::TYPE_ID, &original, &loaded, sizeof(loaded) ); EXPECT_EQ( original.arr.count, loaded[0].arr.count ); for( uint32_t i = 0; i < loaded[0].arr.count; ++i ) { EXPECT_EQ( original.arr[i].ptr->Int1, loaded[0].arr[i].ptr->Int1 ); EXPECT_EQ( original.arr[i].ptr->Int2, loaded[0].arr[i].ptr->Int2 ); } EXPECT_NE( loaded[0].arr[0].ptr, loaded[0].arr[1].ptr ); EXPECT_NE( loaded[0].arr[0].ptr, loaded[0].arr[2].ptr ); EXPECT_NE( loaded[0].arr[0].ptr, loaded[0].arr[3].ptr ); EXPECT_NE( loaded[0].arr[0].ptr, loaded[0].arr[4].ptr ); EXPECT_EQ( loaded[0].arr[1].ptr, loaded[0].arr[2].ptr ); }
TYPED_TEST(DLBase, array_with_sub_array2) { uint32_t array_data1[] = { 1337, 7331, 13, 37, 133 } ; uint32_t array_data2[] = { 7, 1, 337 } ; PodArray1 original_array[] = { { { array_data1, DL_ARRAY_LENGTH(array_data1) } }, { { array_data2, DL_ARRAY_LENGTH(array_data2) } } } ; PodArray2 original = { { original_array, DL_ARRAY_LENGTH(original_array) } }; PodArray2 loaded[16]; this->do_the_round_about( PodArray2::TYPE_ID, &original, loaded, sizeof(loaded) ); EXPECT_EQ(original.sub_arr.count, loaded[0].sub_arr.count); EXPECT_EQ(original.sub_arr[0].u32_arr.count, loaded[0].sub_arr[0].u32_arr.count); EXPECT_EQ(original.sub_arr[1].u32_arr.count, loaded[0].sub_arr[1].u32_arr.count); EXPECT_ARRAY_EQ(original.sub_arr[0].u32_arr.count, original.sub_arr[0].u32_arr.data, loaded[0].sub_arr[0].u32_arr.data); EXPECT_ARRAY_EQ(original.sub_arr[1].u32_arr.count, original.sub_arr[1].u32_arr.data, loaded[0].sub_arr[1].u32_arr.data); }
TYPED_TEST(DLBase, array_with_sub_array) { uint32_t array_data[] = { 1337, 7331 } ; PodArray1 original_array[1]; original_array[0].u32_arr.data = array_data; original_array[0].u32_arr.count = DL_ARRAY_LENGTH(array_data); PodArray2 original; original.sub_arr.data = original_array; original.sub_arr.count = DL_ARRAY_LENGTH(original_array); PodArray2 loaded[16]; this->do_the_round_about( PodArray2::TYPE_ID, &original, loaded, sizeof(loaded) ); EXPECT_EQ(original.sub_arr.count, loaded[0].sub_arr.count); EXPECT_EQ(original.sub_arr[0].u32_arr.count, loaded[0].sub_arr[0].u32_arr.count); EXPECT_ARRAY_EQ(original.sub_arr[0].u32_arr.count, original.sub_arr[0].u32_arr.data, loaded[0].sub_arr[0].u32_arr.data); }
static const dl_builtin_type* dl_find_builtin_type( const char* name ) { for( size_t i = 0; i < DL_ARRAY_LENGTH( BUILTIN_TYPES ); ++i ) { const dl_builtin_type* builtin = &BUILTIN_TYPES[i]; if( strcmp( name, builtin->name ) == 0 ) return builtin; } return 0x0; }
TYPED_TEST(DLBase, array_struct_circular_ptr_holder_array ) { // long name! circular_array p1, p2, p3; p1.val = 1337; p2.val = 1338; p3.val = 1339; circular_array_ptr_holder p1_arr[] = { { &p2 }, { &p3 } }; circular_array_ptr_holder p2_arr[] = { { &p1 }, { &p2 } }; circular_array_ptr_holder p3_arr[] = { { &p3 }, { &p1 } }; p1.arr.data = p1_arr; p1.arr.count = DL_ARRAY_LENGTH( p1_arr ); p2.arr.data = p2_arr; p2.arr.count = DL_ARRAY_LENGTH( p2_arr ); p3.arr.data = p3_arr; p3.arr.count = DL_ARRAY_LENGTH( p3_arr ); circular_array loaded[16]; this->do_the_round_about( circular_array::TYPE_ID, &p1, &loaded, sizeof(loaded) ); const circular_array* l1 = &loaded[0]; const circular_array* l2 = loaded[0].arr[0].ptr; const circular_array* l3 = loaded[0].arr[1].ptr; EXPECT_EQ( p1.val, l1->val ); EXPECT_EQ( p1.arr.count, l1->arr.count ); EXPECT_EQ( p2.val, l2->val ); EXPECT_EQ( p2.arr.count, l2->arr.count ); EXPECT_EQ( p3.val, l3->val ); EXPECT_EQ( p3.arr.count, l3->arr.count ); EXPECT_EQ( l1->arr[0].ptr, l2 ); EXPECT_EQ( l1->arr[1].ptr, l3 ); EXPECT_EQ( l2->arr[0].ptr, l1 ); EXPECT_EQ( l2->arr[1].ptr, l2 ); EXPECT_EQ( l3->arr[0].ptr, l3 ); EXPECT_EQ( l3->arr[1].ptr, l1 ); }
TYPED_TEST(DLBase, array_pod1) { uint32_t array_data[8] = { 1337, 7331, 13, 37, 133, 7, 1, 337 } ; PodArray1 original = { { array_data, DL_ARRAY_LENGTH( array_data ) } }; PodArray1 loaded[16]; this->do_the_round_about( PodArray1::TYPE_ID, &original, loaded, sizeof(loaded) ); EXPECT_EQ(original.u32_arr.count, loaded[0].u32_arr.count); EXPECT_ARRAY_EQ(original.u32_arr.count, original.u32_arr.data, loaded[0].u32_arr.data); }
TEST_F(DLReflect, pods) { dl_type_info_t Info; dl_member_info_t Members[128]; memset( &Info, 0x0, sizeof(dl_type_info_t) ); EXPECT_DL_ERR_OK(dl_reflect_get_type_info( Ctx, Pods::TYPE_ID, &Info )); EXPECT_DL_ERR_OK(dl_reflect_get_type_members( Ctx, Pods::TYPE_ID, Members, DL_ARRAY_LENGTH(Members) )); EXPECT_EQ ((uint32_t)Pods::TYPE_ID, Info.tid ); EXPECT_STREQ("Pods", Info.name); EXPECT_EQ (10u, Info.member_count); EXPECT_STREQ("i8", Members[0].name); EXPECT_EQ (DL_TYPE_ATOM_POD, Members[0].type & DL_TYPE_ATOM_MASK); EXPECT_EQ (DL_TYPE_STORAGE_INT8, Members[0].type & DL_TYPE_STORAGE_MASK); EXPECT_STREQ("i16" , Members[1].name); EXPECT_EQ (DL_TYPE_ATOM_POD, Members[1].type & DL_TYPE_ATOM_MASK); EXPECT_EQ (DL_TYPE_STORAGE_INT16, Members[1].type & DL_TYPE_STORAGE_MASK); EXPECT_STREQ("i32", Members[2].name); EXPECT_EQ (DL_TYPE_ATOM_POD, Members[2].type & DL_TYPE_ATOM_MASK); EXPECT_EQ (DL_TYPE_STORAGE_INT32, Members[2].type & DL_TYPE_STORAGE_MASK); EXPECT_STREQ("i64", Members[3].name); EXPECT_EQ (DL_TYPE_ATOM_POD, Members[3].type & DL_TYPE_ATOM_MASK); EXPECT_EQ (DL_TYPE_STORAGE_INT64, Members[3].type & DL_TYPE_STORAGE_MASK); EXPECT_STREQ("u8", Members[4].name); EXPECT_EQ (DL_TYPE_ATOM_POD, Members[4].type & DL_TYPE_ATOM_MASK); EXPECT_EQ (DL_TYPE_STORAGE_UINT8, Members[4].type & DL_TYPE_STORAGE_MASK); EXPECT_STREQ("u16", Members[5].name); EXPECT_EQ (DL_TYPE_ATOM_POD, Members[5].type & DL_TYPE_ATOM_MASK); EXPECT_EQ (DL_TYPE_STORAGE_UINT16, Members[5].type & DL_TYPE_STORAGE_MASK); EXPECT_STREQ("u32", Members[6].name); EXPECT_EQ (DL_TYPE_ATOM_POD, Members[6].type & DL_TYPE_ATOM_MASK); EXPECT_EQ (DL_TYPE_STORAGE_UINT32, Members[6].type & DL_TYPE_STORAGE_MASK); EXPECT_STREQ("u64", Members[7].name); EXPECT_EQ (DL_TYPE_ATOM_POD, Members[7].type & DL_TYPE_ATOM_MASK); EXPECT_EQ (DL_TYPE_STORAGE_UINT64, Members[7].type & DL_TYPE_STORAGE_MASK); EXPECT_STREQ("f32", Members[8].name); EXPECT_EQ (DL_TYPE_ATOM_POD, Members[8].type & DL_TYPE_ATOM_MASK); EXPECT_EQ (DL_TYPE_STORAGE_FP32, Members[8].type & DL_TYPE_STORAGE_MASK); EXPECT_STREQ("f64", Members[9].name); EXPECT_EQ (DL_TYPE_ATOM_POD, Members[9].type & DL_TYPE_ATOM_MASK); EXPECT_EQ (DL_TYPE_STORAGE_FP64, Members[9].type & DL_TYPE_STORAGE_MASK); }
TYPED_TEST(DLBase, array_string_null) { const char* array_data[] = { "I like", "the", 0x0, "cowbells of doom!" }; StringArray original = { { array_data, DL_ARRAY_LENGTH(array_data) } }; StringArray loaded[10]; this->do_the_round_about( StringArray::TYPE_ID, &original, loaded, sizeof(loaded) ); EXPECT_STREQ(original.Strings[0], loaded[0].Strings[0]); EXPECT_STREQ(original.Strings[1], loaded[0].Strings[1]); EXPECT_STREQ(original.Strings[2], loaded[0].Strings[2]); EXPECT_STREQ(original.Strings[3], loaded[0].Strings[3]); }
TYPED_TEST(DLBase, array_string_with_commas) { const char* array_data[] = { "I li,ke", "the", "13,37 ", "cowbe,lls of doom!" }; // TODO: test string-arrays with , in strings. StringArray original = { { array_data, DL_ARRAY_LENGTH(array_data) } }; StringArray loaded[10]; this->do_the_round_about( StringArray::TYPE_ID, &original, loaded, sizeof(loaded) ); EXPECT_STREQ(original.Strings[0], loaded[0].Strings[0]); EXPECT_STREQ(original.Strings[1], loaded[0].Strings[1]); EXPECT_STREQ(original.Strings[2], loaded[0].Strings[2]); EXPECT_STREQ(original.Strings[3], loaded[0].Strings[3]); }
TEST_F(DLError, type_mismatch_returned) { // testing that DL_ERROR_TYPE_MISMATCH is returned if provided type is not matching type stored in instance unused u; size_t dummy; unsigned char packed[sizeof(unused) * 10]; // large enough buffer! unsigned char swaped[sizeof(unused) * 10]; // large enough buffer! unsigned char bus_buffer[sizeof(unused) * 10]; // large enough buffer! char bus_text[sizeof(unused) * 10]; // large enough buffer! dl_endian_t other_endian = DL_ENDIAN_HOST == DL_ENDIAN_LITTLE ? DL_ENDIAN_BIG : DL_ENDIAN_LITTLE; EXPECT_DL_ERR_OK( dl_instance_store( Ctx, unused::TYPE_ID, &u, packed, DL_ARRAY_LENGTH(packed), 0x0 ) ); EXPECT_DL_ERR_OK( dl_convert( Ctx, unused::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), swaped, DL_ARRAY_LENGTH(swaped), other_endian, sizeof(void*), 0x0 ) ); // test all functions in... #define EXPECT_DL_ERR_TYPE_MISMATCH( err ) EXPECT_DL_ERR_EQ( DL_ERROR_TYPE_MISMATCH, err ) Pods p; // dl.h EXPECT_DL_ERR_TYPE_MISMATCH( dl_instance_load( Ctx, Pods::TYPE_ID, &p, sizeof(Pods), packed, DL_ARRAY_LENGTH(packed), 0x0 ) ); // dl_convert.h EXPECT_DL_ERR_TYPE_MISMATCH( dl_convert( Ctx, Pods::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), bus_buffer, DL_ARRAY_LENGTH(bus_buffer), other_endian, sizeof(void*), 0x0 ) ); EXPECT_DL_ERR_TYPE_MISMATCH( dl_convert( Ctx, Pods::TYPE_ID, swaped, DL_ARRAY_LENGTH(swaped), bus_buffer, DL_ARRAY_LENGTH(bus_buffer), DL_ENDIAN_HOST, sizeof(void*), 0x0 ) ); EXPECT_DL_ERR_TYPE_MISMATCH( dl_convert_inplace( Ctx, Pods::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), other_endian, sizeof(void*), 0x0 ) ); EXPECT_DL_ERR_TYPE_MISMATCH( dl_convert_inplace( Ctx, Pods::TYPE_ID, swaped, DL_ARRAY_LENGTH(swaped), DL_ENDIAN_HOST, sizeof(void*), 0x0 ) ); EXPECT_DL_ERR_TYPE_MISMATCH( dl_convert_calc_size( Ctx, Pods::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), sizeof(void*), &dummy ) ); EXPECT_DL_ERR_TYPE_MISMATCH( dl_convert_calc_size( Ctx, Pods::TYPE_ID, swaped, DL_ARRAY_LENGTH(swaped), sizeof(void*), &dummy ) ); // dl_txt.h EXPECT_DL_ERR_TYPE_MISMATCH( dl_txt_unpack( Ctx, Pods::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), bus_text, DL_ARRAY_LENGTH(bus_text), 0x0 ) ); EXPECT_DL_ERR_TYPE_MISMATCH( dl_txt_unpack_calc_size( Ctx, Pods::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), &dummy ) ); #undef EXPECT_DL_ERR_TYPE_MISMATCH }
TEST_F(DLError, version_mismatch_returned) { unused u; size_t dummy; unsigned char packed[sizeof(unused) * 10]; // large enough buffer! unsigned char swaped[sizeof(unused) * 10]; // large enough buffer! unsigned char bus_buffer[sizeof(unused) * 10]; // large enough buffer! char bus_text[sizeof(unused) * 10]; // large enough buffer! dl_endian_t other_endian = DL_ENDIAN_HOST == DL_ENDIAN_LITTLE ? DL_ENDIAN_BIG : DL_ENDIAN_LITTLE; EXPECT_DL_ERR_OK( dl_instance_store( Ctx, unused::TYPE_ID, &u, packed, DL_ARRAY_LENGTH(packed), 0x0 ) ); EXPECT_DL_ERR_OK( dl_convert( Ctx, unused::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), swaped, DL_ARRAY_LENGTH(swaped), other_endian, sizeof(void*), 0x0 ) ); // testing that errors are returned correctly by modding data. union { unsigned int* instance_version; unsigned char* instance; } conv; conv.instance = packed; unsigned int* instance_version; instance_version = conv.instance_version + 1; EXPECT_EQ(1u, *instance_version); *instance_version = 0xFFFFFFFF; conv.instance = swaped; instance_version = conv.instance_version + 1; EXPECT_EQ(0x01000000u, *instance_version); *instance_version = 0xFFFFFFFF; // test all functions in... #define EXPECT_DL_ERR_VERSION_MISMATCH( err ) EXPECT_DL_ERR_EQ( DL_ERROR_VERSION_MISMATCH, err ) Pods p; // dl.h EXPECT_DL_ERR_VERSION_MISMATCH( dl_instance_load( Ctx, unused::TYPE_ID, &p, sizeof(Pods), packed, DL_ARRAY_LENGTH(packed), 0x0 ) ); // dl_convert.h EXPECT_DL_ERR_VERSION_MISMATCH( dl_convert( Ctx, unused::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), bus_buffer, DL_ARRAY_LENGTH(bus_buffer), other_endian, sizeof(void*), 0x0 ) ); EXPECT_DL_ERR_VERSION_MISMATCH( dl_convert( Ctx, unused::TYPE_ID, swaped, DL_ARRAY_LENGTH(swaped), bus_buffer, DL_ARRAY_LENGTH(bus_buffer), DL_ENDIAN_HOST, sizeof(void*), 0x0 ) ); EXPECT_DL_ERR_VERSION_MISMATCH( dl_convert_inplace( Ctx, unused::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), other_endian, sizeof(void*), 0x0 ) ); EXPECT_DL_ERR_VERSION_MISMATCH( dl_convert_inplace( Ctx, unused::TYPE_ID, swaped, DL_ARRAY_LENGTH(swaped), DL_ENDIAN_HOST, sizeof(void*), 0x0 ) ); EXPECT_DL_ERR_VERSION_MISMATCH( dl_convert_calc_size( Ctx, unused::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), sizeof(void*), &dummy ) ); EXPECT_DL_ERR_VERSION_MISMATCH( dl_convert_calc_size( Ctx, unused::TYPE_ID, swaped, DL_ARRAY_LENGTH(swaped), sizeof(void*), &dummy ) ); // dl_txt.h EXPECT_DL_ERR_VERSION_MISMATCH( dl_txt_unpack( Ctx, unused::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), bus_text, DL_ARRAY_LENGTH(bus_text), 0x0 ) ); EXPECT_DL_ERR_VERSION_MISMATCH( dl_txt_unpack_calc_size( Ctx, unused::TYPE_ID, packed, DL_ARRAY_LENGTH(packed), &dummy ) ); #undef EXPECT_DL_ERR_VERSION_MISMATCH }
TYPED_TEST(DLBase, array_enum) { TestEnum2 array_data[8] = { TESTENUM2_VALUE1, TESTENUM2_VALUE2, TESTENUM2_VALUE3, TESTENUM2_VALUE4, TESTENUM2_VALUE4, TESTENUM2_VALUE3, TESTENUM2_VALUE2, TESTENUM2_VALUE1 } ; ArrayEnum original = { { array_data, DL_ARRAY_LENGTH(array_data) } }; ArrayEnum loaded[16]; this->do_the_round_about( ArrayEnum::TYPE_ID, &original, loaded, sizeof(loaded) ); EXPECT_EQ(original.EnumArr.count, loaded[0].EnumArr.count); EXPECT_EQ(original.EnumArr[0], loaded[0].EnumArr[0]); EXPECT_EQ(original.EnumArr[1], loaded[0].EnumArr[1]); EXPECT_EQ(original.EnumArr[2], loaded[0].EnumArr[2]); EXPECT_EQ(original.EnumArr[3], loaded[0].EnumArr[3]); EXPECT_EQ(original.EnumArr[4], loaded[0].EnumArr[4]); EXPECT_EQ(original.EnumArr[5], loaded[0].EnumArr[5]); EXPECT_EQ(original.EnumArr[6], loaded[0].EnumArr[6]); EXPECT_EQ(original.EnumArr[7], loaded[0].EnumArr[7]); }
TYPED_TEST(DLBase, array_struct) { Pods2 array_data[4] = { { 1, 2}, { 3, 4 }, { 5, 6 }, { 7, 8 } } ; StructArray1 original = { { array_data, DL_ARRAY_LENGTH(array_data) } }; StructArray1 loaded[16]; this->do_the_round_about( StructArray1::TYPE_ID, &original, loaded, sizeof(loaded) ); EXPECT_EQ(original.Array.count, loaded[0].Array.count); EXPECT_EQ(original.Array[0].Int1, loaded[0].Array[0].Int1); EXPECT_EQ(original.Array[0].Int2, loaded[0].Array[0].Int2); EXPECT_EQ(original.Array[1].Int1, loaded[0].Array[1].Int1); EXPECT_EQ(original.Array[1].Int2, loaded[0].Array[1].Int2); EXPECT_EQ(original.Array[2].Int1, loaded[0].Array[2].Int1); EXPECT_EQ(original.Array[2].Int2, loaded[0].Array[2].Int2); EXPECT_EQ(original.Array[3].Int1, loaded[0].Array[3].Int1); EXPECT_EQ(original.Array[3].Int2, loaded[0].Array[3].Int2); }
void inplace_load_test::do_it( dl_ctx_t dl_ctx, dl_typeid_t type, unsigned char* store_buffer, size_t store_size, unsigned char* out_buffer, size_t* out_size ) { // copy stored instance into temp-buffer unsigned char inplace_buffer[4096]; memset( inplace_buffer, 0xFE, DL_ARRAY_LENGTH(inplace_buffer) ); memcpy( inplace_buffer, store_buffer, store_size ); // load inplace void* loaded_instance = 0x0; size_t consumed = 0; EXPECT_DL_ERR_OK( dl_instance_load_inplace( dl_ctx, type, inplace_buffer, store_size, &loaded_instance, &consumed )); EXPECT_EQ( store_size, consumed ); EXPECT_EQ( (unsigned char)0xFE, (unsigned char)inplace_buffer[store_size + 1] ); // no overwrite by inplace load! // store to out-buffer EXPECT_DL_ERR_OK( dl_instance_calc_size( dl_ctx, type, loaded_instance, out_size ) ); EXPECT_DL_ERR_OK( dl_instance_store( dl_ctx, type, loaded_instance, out_buffer, *out_size, 0x0 ) ); }
static int dl_parse_type( dl_ctx_t ctx, dl_txt_read_substr* type, dl_member_desc* member, dl_txt_read_ctx* read_state ) { #define DL_PARSE_TYPE_VALID_FMT_STR "\nvalid formats, 'type', 'type*', 'type[count]', 'type[]', 'bitfield:bits'" // ... strip whitespace ... char type_name[2048]; size_t type_name_len = 0; DL_ASSERT( (size_t)type->len < DL_ARRAY_LENGTH( type_name ) ); const char* iter = type->str; const char* end = type->str + type->len; while( ( iter != end ) && ( isalnum( *iter ) || *iter == '_' ) ) { type_name[type_name_len++] = *iter; ++iter; } type_name[type_name_len] = '\0'; bool is_ptr = false; bool is_array = false; bool is_inline_array = false; unsigned int inline_array_len = 0; const char* inline_array_enum_value = 0x0; size_t inline_array_enum_value_size = 0; if( iter != end ) { if( *iter == '*' ) { is_ptr = true; if( iter[1] == '[' ) ++iter; } switch( *iter ) { case '[': { ++iter; if( *iter == ']' ) is_array = true; else { char* next = 0x0; inline_array_len = (unsigned int)strtoul( iter, &next, 0 ); if( iter == next ) { // ... failed to parse inline array as number, try it as an enum .. while( *next != ']' && ( isalnum(*next) || *next == '_' ) ) ++next; if( *next != ']' ) dl_txt_read_failed( ctx, read_state, DL_ERROR_TXT_PARSE_ERROR, "%.*s is not a valid type", type->len, type->str ); inline_array_enum_value = iter; inline_array_enum_value_size = (size_t)(next - iter); } else { if( *next != ']' ) dl_txt_read_failed( ctx, read_state, DL_ERROR_TXT_PARSE_ERROR, "%.*s is not a valid type", type->len, type->str ); } iter = next + 1; is_inline_array = true; } } break; case ':': { if(strcmp( "bitfield", type_name ) != 0) dl_txt_read_failed( ctx, read_state, DL_ERROR_TXT_PARSE_ERROR, "found char (':') when parsing type '%.*s', this is only valid for type 'bitfield'" DL_PARSE_TYPE_VALID_FMT_STR, type->len, type->str ); ++iter; member->type = dl_make_type( DL_TYPE_ATOM_BITFIELD, DL_TYPE_STORAGE_UINT8 ); member->type_id = 0; char* next = 0x0; unsigned int bits = (unsigned int)strtoul( iter, &next, 0 ); if( iter == next || *next != '\"' ) dl_txt_read_failed( ctx, read_state, DL_ERROR_TXT_PARSE_ERROR, "bitfield has a bad format, should be \"bitfield:<num_bits>\"" ); member->set_bitfield_bits( bits ); // type etc? return 1; } break; case '*': { // ignore ... } break; default: { dl_txt_read_failed( ctx, read_state, DL_ERROR_TXT_PARSE_ERROR, "invalid char ('%c') found when parsing type '%.*s'\n" DL_PARSE_TYPE_VALID_FMT_STR, *iter, type->len, type->str ); } } } if( strcmp( "bitfield", type_name ) == 0 ) dl_txt_read_failed( ctx, read_state, DL_ERROR_TXT_PARSE_ERROR, "bitfield has a bad format, should be \"bitfield:<num_bits>\"" ); dl_type_atom_t atom = DL_TYPE_ATOM_POD; if( is_array ) atom = DL_TYPE_ATOM_ARRAY; if( is_inline_array ) atom = DL_TYPE_ATOM_INLINE_ARRAY; const dl_builtin_type* builtin = dl_find_builtin_type( type_name ); if( builtin ) { if( is_ptr ) dl_txt_read_failed( ctx, read_state, DL_ERROR_TXT_PARSE_ERROR, "pointer to pod is not supported!" ); member->type = dl_make_type( atom, builtin->type ); member->type_id = 0; dl_set_member_size_and_align_from_builtin( builtin->type, member ); } else { member->type = dl_make_type( atom, is_ptr ? DL_TYPE_STORAGE_PTR : DL_TYPE_STORAGE_STRUCT ); member->type_id = dl_internal_hash_string( type_name ); } if( is_inline_array ) { member->set_inline_array_cnt( inline_array_len ); if( inline_array_len == 0 ) { // If the inline array size is an enum we have to lookup the size when we are sure that all enums are parsed, temporarily store pointer and string-length // in size/align of member. if( sizeof(void*) == 8 ) { member->set_size( (uint32_t)( (uint64_t)inline_array_enum_value & 0xFFFFFFFF ), (uint32_t)( ( (uint64_t)inline_array_enum_value >> 32 ) & 0xFFFFFFFF ) ); member->set_align( (uint32_t)(inline_array_enum_value_size & 0xFFFFFFFF ), 0 ); } else { member->set_size( (uint32_t)((uint64_t)inline_array_enum_value & 0xFFFFFFFF), 0 ); member->set_align( (uint32_t)(inline_array_enum_value_size & 0xFFFFFFFF ), 0 ); } }
void add( uint8_t* addr ) { DL_ASSERT( next_addr < DL_ARRAY_LENGTH( addresses ) ); DL_ASSERT( !patched( addr ) ); addresses[next_addr++] = addr; }