Пример #1
0
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;
            }
        }
    }
}
Пример #2
0
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);
}
Пример #3
0
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;
    }
}
Пример #4
0
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;
}
Пример #5
0
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");
    }
}