示例#1
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;
    }
}
示例#2
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");
    }
}