static void dr_metalib_validate_align_i(error_monitor_t em, LPDRMETALIB metalib) { int meta_pos; int meta_count; meta_count = dr_lib_meta_num(metalib); for(meta_pos = 0; meta_pos < meta_count; ++meta_pos) { LPDRMETA meta; int entry_pos; int entry_count; meta = dr_lib_meta_at(metalib, meta_pos); entry_count = dr_meta_entry_num(meta); for(entry_pos = 0; entry_pos < entry_count; ++entry_pos) { LPDRMETAENTRY entry = dr_meta_entry_at(meta, entry_pos); int align = dr_entry_align(entry); if (align != 1 && align != 2 && align != 4 && align != 8) { CPE_ERROR( em, "%s.%s: type align %d error", dr_meta_name(meta), dr_entry_name(entry), align); continue; } if ((int)dr_entry_data_start_pos(entry) % align) { CPE_ERROR( em, "%s.%s: start pos error, align is %d, startpos is %d", dr_meta_name(meta), dr_entry_name(entry), align, (int)dr_entry_data_start_pos(entry)); continue; } } } }
const char * dr_meta_copy_union_find_select_entry_name( const char * src_data, size_t src_capacity, LPDRMETAENTRY src_entry, LPDRMETA src_meta) { LPDRMETAENTRY src_select_entry; LPDRMETAENTRY src_union_entry; int32_t src_union_entry_id; int32_t src_union_entry_pos; src_select_entry = dr_entry_select_entry(src_entry); if (src_select_entry == 0) return NULL; if (src_entry->m_select_data_start_pos + dr_entry_element_size(src_select_entry) > src_capacity) return NULL; if (dr_entry_try_read_int32( &src_union_entry_id, src_data + src_entry->m_select_data_start_pos, src_select_entry, NULL) != 0) { return NULL; } src_union_entry_pos = dr_meta_find_entry_idx_by_id(src_meta, src_union_entry_id); if (src_union_entry_pos < 0) return NULL; src_union_entry = dr_meta_entry_at(src_meta, src_union_entry_pos); if (src_union_entry == NULL) return NULL; return dr_entry_name(src_union_entry); }
void dr_meta_copy_same_entry( void * des_data, size_t des_capacity, LPDRMETA des_meta, void const * src_data, size_t src_capacity, LPDRMETA src_meta, int policy, error_monitor_t em) { struct CopySameEntryProcessStack processStack[CPE_DR_MAX_LEVEL]; int stackPos; assert(des_data); assert(des_meta); assert(src_data); assert(src_meta); processStack[0].m_des_meta = des_meta; processStack[0].m_des_entry = dr_meta_entry_at(des_meta, 0); processStack[0].m_des_entry_pos = 0; processStack[0].m_des_entry_count = des_meta->m_entry_count; processStack[0].m_array_pos = 0; processStack[0].m_des_data = (char *)des_data; processStack[0].m_des_capacity = des_capacity; processStack[0].m_src_meta = src_meta; processStack[0].m_src_data = (const char *)src_data; processStack[0].m_src_capacity = src_capacity; for(stackPos = 0; stackPos >= 0;) { struct CopySameEntryProcessStack * curStack; assert(stackPos < CPE_DR_MAX_LEVEL); curStack = &processStack[stackPos]; if (curStack->m_des_meta == NULL) { --stackPos; continue; } for(; curStack->m_des_entry_pos < curStack->m_des_entry_count && curStack->m_des_entry ; ++curStack->m_des_entry_pos , curStack->m_array_pos = 0 , curStack->m_des_entry = dr_meta_entry_at(curStack->m_des_meta, curStack->m_des_entry_pos) ) { size_t des_element_size, src_element_size; LPDRMETAENTRY src_entry; int32_t des_array_count_max, src_array_count_max; LOOPENTRY: des_element_size = dr_entry_element_size(curStack->m_des_entry); if (des_element_size == 0) continue; src_entry = dr_meta_find_entry_by_name(curStack->m_src_meta, dr_entry_name(curStack->m_des_entry)); if (src_entry == 0) continue; src_element_size = dr_entry_element_size(src_entry); if (src_element_size == 0) continue; if (!dr_meta_copy_check_type_copyable(curStack->m_des_entry->m_type, src_entry->m_type)) continue; if (!dr_meta_copy_check_array_copyable(curStack->m_des_entry->m_array_count, src_entry->m_array_count)) continue; des_array_count_max = curStack->m_des_entry->m_array_count; src_array_count_max = src_entry->m_array_count; if (src_array_count_max != 1) { LPDRMETAENTRY srcRefer = dr_entry_array_refer_entry(src_entry); if (srcRefer) { int32_t readBuf; if (dr_ctype_try_read_int32( &readBuf, curStack->m_src_data + src_entry->m_array_refer_data_start_pos, src_entry->m_type, 0) == 0) { src_array_count_max = readBuf; } } } for(; curStack->m_array_pos < des_array_count_max && curStack->m_array_pos < src_array_count_max ; ++curStack->m_array_pos) { char * des_entry_data; const char * src_entry_data; size_t des_entry_capacity, des_left_capacity; size_t src_entry_capacity, src_left_capacity; des_entry_data = curStack->m_des_data + curStack->m_des_entry->m_data_start_pos + (des_element_size * curStack->m_array_pos); if ((size_t)(des_entry_data - curStack->m_des_data) > curStack->m_des_capacity) continue; des_left_capacity = curStack->m_des_capacity - (des_entry_data - curStack->m_des_data); des_entry_capacity = des_element_size; if ((curStack->m_des_entry_pos + 1 == curStack->m_des_meta->m_entry_count && curStack->m_array_pos + 1 == des_array_count_max) /*last element*/ || des_entry_capacity > des_left_capacity) { des_entry_capacity = des_left_capacity; } src_entry_data = curStack->m_src_data + src_entry->m_data_start_pos + (src_element_size * curStack->m_array_pos); if ((size_t)(src_entry_data - curStack->m_src_data) > curStack->m_src_capacity) continue; src_left_capacity = curStack->m_src_capacity - (src_entry_data - curStack->m_src_data); src_entry_capacity = src_element_size; if ((src_entry == dr_meta_entry_at(curStack->m_src_meta, curStack->m_src_meta->m_entry_count - 1) && curStack->m_array_pos + 1 == src_array_count_max) /*last element*/ || des_entry_capacity > des_left_capacity) { src_entry_capacity = src_left_capacity; } if (curStack->m_des_entry->m_type <= CPE_DR_TYPE_COMPOSITE) { struct CopySameEntryProcessStack * nextStack; if (stackPos + 1 >= CPE_DR_MAX_LEVEL) continue; nextStack = &processStack[stackPos + 1]; nextStack->m_des_meta = dr_entry_ref_meta(curStack->m_des_entry); if (nextStack->m_des_meta == 0) continue; nextStack->m_src_meta = dr_entry_ref_meta(src_entry); if (nextStack->m_src_meta == 0) continue; nextStack->m_des_data = des_entry_data; nextStack->m_des_capacity = des_entry_capacity; nextStack->m_array_pos = 0; nextStack->m_src_data = src_entry_data; nextStack->m_src_capacity = src_entry_capacity; nextStack->m_des_entry_pos = 0; nextStack->m_des_entry_count = nextStack->m_des_meta->m_entry_count; nextStack->m_des_entry = dr_meta_entry_at(nextStack->m_des_meta, 0); if (curStack->m_des_entry->m_type == CPE_DR_TYPE_UNION) { const char * union_entry_name; union_entry_name = dr_meta_copy_union_find_select_entry_name( curStack->m_src_data, curStack->m_src_capacity, src_entry, nextStack->m_src_meta); if (union_entry_name) { nextStack->m_des_entry_pos = dr_meta_find_entry_idx_by_name(nextStack->m_des_meta, union_entry_name); if (nextStack->m_des_entry_pos < 0) continue; nextStack->m_des_entry = dr_meta_entry_at(nextStack->m_des_meta, nextStack->m_des_entry_pos); nextStack->m_des_entry_count = nextStack->m_des_entry_pos + 1; if (nextStack->m_des_entry->m_id != -1) { LPDRMETAENTRY des_select_entry; des_select_entry = dr_entry_select_entry(curStack->m_des_entry); if (des_select_entry) { if (curStack->m_des_entry->m_select_data_start_pos + dr_entry_element_size(des_select_entry) <= curStack->m_des_capacity) { dr_entry_set_from_int32( curStack->m_des_data + curStack->m_des_entry->m_select_data_start_pos, nextStack->m_des_entry->m_id, des_select_entry, NULL); } } } } } if (nextStack->m_des_entry == 0) { } ++curStack->m_array_pos; ++stackPos; curStack = nextStack; goto LOOPENTRY; } else { dr_entry_set_from_ctype(des_entry_data, src_entry_data, src_entry->m_type, curStack->m_des_entry, 0); } } if (curStack->m_des_entry->m_array_count != 1) { LPDRMETAENTRY refer = dr_entry_array_refer_entry(curStack->m_des_entry); if (refer) { dr_entry_set_from_int32( curStack->m_des_data + curStack->m_des_entry->m_array_refer_data_start_pos, curStack->m_array_pos, refer, 0); } } } --stackPos; } }
dr_dm_data_t dr_dm_data_create(dr_dm_manage_t mgr, const void * data, size_t data_size, const char ** duplicate_index) { char * buf; dr_dm_data_t role; size_t data_capacity; dr_dm_data_id_t role_id; int generate_role_id; size_t index_count; struct cpe_hash_it index_it; struct dr_dm_data_index * index; size_t i; index_count = cpe_hash_table_count(&mgr->m_indexes); if (duplicate_index) *duplicate_index = NULL; if (mgr->m_role_meta == NULL) { CPE_ERROR( mgr->m_em, "%s: dr_dm_data_create: role meta not exist!", dr_dm_manage_name(mgr)); return NULL; } if (mgr->m_id_index == NULL) { CPE_ERROR( mgr->m_em, "%s: dr_dm_data_create: role id entry not exist!", dr_dm_manage_name(mgr)); return NULL; } data_capacity = dr_meta_size(mgr->m_role_meta); if (data_size > data_capacity) { CPE_ERROR( mgr->m_em, "%s: dr_dm_data_create: data too long, data_size=%d, data_capacity=%d!", dr_dm_manage_name(mgr), (int)data_size, (int)data_capacity); return NULL; } generate_role_id = 0; role_id = dr_entry_read_int64(data, mgr->m_id_index->m_entry); if (role_id == 0) { if (mgr->m_id_generate) { if (gd_id_generator_generate(&role_id, mgr->m_id_generate) != 0) { CPE_ERROR( mgr->m_em, "%s: dr_dm_data_create: generate id from %s fail!", dr_dm_manage_name(mgr), gd_id_generator_name(mgr->m_id_generate)); return NULL; } else { generate_role_id = 1; } } } buf = (char *)mem_alloc( mgr->m_alloc, sizeof(struct cpe_hash_entry) * index_count + sizeof(struct dr_dm_data) + data_capacity); if (buf == NULL) return NULL; role = (dr_dm_data_t)(buf + sizeof(struct cpe_hash_entry) * index_count); role->m_mgr = mgr; memcpy(dr_dm_data_data(role), data, data_capacity); if (generate_role_id) { if (dr_entry_set_from_int64(dr_dm_data_data(role), role_id, mgr->m_id_index->m_entry, NULL) != 0) { CPE_ERROR( mgr->m_em, "%s: dr_dm_data_create: set generated id to data fail!", dr_dm_manage_name(mgr)); mem_free(mgr->m_alloc, buf); return NULL; } } for(i = 0; i < index_count; ++i) { cpe_hash_entry_init(((struct cpe_hash_entry*)buf) + i); } cpe_hash_it_init(&index_it, &mgr->m_indexes); while((index = cpe_hash_it_next(&index_it))) { if (dr_dm_data_index_add(index, role) != 0) { struct dr_dm_data_index * index_fall_back; CPE_ERROR( mgr->m_em, "%s: dr_dm_data_create: add to index %s: duplicate!", dr_dm_manage_name(mgr), dr_entry_name(index->m_entry)); if (duplicate_index) *duplicate_index = dr_dm_data_index_name(index); cpe_hash_it_init(&index_it, &mgr->m_indexes); while((index_fall_back = cpe_hash_it_next(&index_it)) && index_fall_back != index) { dr_dm_data_index_remove(index_fall_back, role); } mem_free(mgr->m_alloc, buf); return NULL; } } return role; }
static void cpe_dr_generate_h_metas(write_stream_t stream, dr_metalib_source_t source, cpe_dr_generate_ctx_t ctx) { struct dr_metalib_source_element_it element_it; dr_metalib_source_element_t element; int curent_pack; int packed; curent_pack = 0; packed = 0; dr_metalib_source_elements(&element_it, source); while((element = dr_metalib_source_element_next(&element_it))) { LPDRMETA meta; int entry_pos; if (dr_metalib_source_element_type(element) != dr_metalib_source_element_type_meta) continue; meta = dr_lib_find_meta_by_name(ctx->m_metalib, dr_metalib_source_element_name(element)); if (meta == NULL) continue; if (dr_meta_align(meta) != curent_pack) { stream_printf(stream, "\n#pragma pack(1)\n"); curent_pack = dr_meta_align(meta); packed = 1; } stream_printf(stream, "\nstruct %s {", dr_meta_name(meta)); for(entry_pos = 0; entry_pos < dr_meta_entry_num(meta); ++entry_pos) { LPDRMETAENTRY entry = dr_meta_entry_at(meta, entry_pos); stream_printf(stream, "\n"); stream_printf(stream, " "); switch(dr_entry_type(entry)) { case CPE_DR_TYPE_UNION: case CPE_DR_TYPE_STRUCT: { LPDRMETA ref_meta; ref_meta = dr_entry_ref_meta(entry); if (ref_meta == NULL) continue; stream_printf(stream, "%s %s %s", dr_type_name(dr_entry_type(entry)), dr_meta_name(ref_meta), dr_entry_name(entry)); break; } case CPE_DR_TYPE_STRING: { stream_printf(stream, "char %s[%d]", dr_entry_name(entry), dr_entry_size(entry)); break; } default: { stream_printf(stream, "%s_t %s", dr_type_name(dr_entry_type(entry)), dr_entry_name(entry)); break; } } if (dr_entry_array_count(entry) != 1) { stream_printf(stream, "[%d]", dr_entry_array_count(entry) < 1 ? 1 : dr_entry_array_count(entry)); } stream_printf(stream, ";"); } stream_printf(stream, "\n};\n"); } if (packed) { stream_printf(stream, "\n#pragma pack()\n\n"); } }