Example #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;
    }
}
Example #2
0
 int findEntryIdx(const char * name) const { return dr_meta_find_entry_idx_by_name(*this, name); }