+ /* Send the pointed data only if not already sent */
+ if (*(void**)src == NULL) {
+ VERB0("Not copying NULL referenced data");
+ *(void**)dst = NULL;
+ break;
+ }
+ o_ref=(char**)src;
+
+ reference_is_to_cpy = 0;
+ TRY {
+ if (detect_cycle)
+ /* return ignored. Just checking whether it's known or not */
+ n_ref=xbt_dict_get_ext(refs,(char*)o_ref, sizeof(char*));
+ else
+ reference_is_to_cpy = 1;
+ } CATCH(e) {
+ if (e.category != not_found_error)
+ RETHROW;
+ reference_is_to_cpy = 1;
+ xbt_ex_free(e);
+ }
+
+ if (reference_is_to_cpy) {
+ int subsubcount = 0;
+ void *l_referenced=NULL;
+ VERB2("Copy a ref to '%s' referenced at %p",sub_type->name, (void*)*o_ref);
+
+ if (!pointer_type) {
+ pointer_type = gras_datadesc_by_name("data pointer");
+ xbt_assert(pointer_type);
+ }
+
+ if (sub_type->category_code == e_gras_datadesc_type_cat_array) {
+ /* Damn. Reference to a dynamic array. Allocating the space for it
+ is more complicated */
+ gras_dd_cat_array_t array_data = sub_type->category.array_data;
+ gras_datadesc_type_t subsub_type;
+
+ subsub_type = array_data.type;
+ subsubcount = array_data.fixed_size;
+ if (subsubcount == 0)
+ subsubcount = array_data.dynamic_size(subsub_type,state,*o_ref);
+
+ gras_dd_alloc_ref(refs,
+ subsub_type->size[GRAS_THISARCH] * subsubcount,
+ o_ref,pointer_type->size[GRAS_THISARCH],
+ (char**)&l_referenced,
+ detect_cycle);
+ } else {
+ gras_dd_alloc_ref(refs,sub_type->size[GRAS_THISARCH],
+ o_ref,pointer_type->size[GRAS_THISARCH],
+ (char**)&l_referenced,
+ detect_cycle);
+ }
+
+ count += gras_datadesc_copy_rec(state,refs, sub_type,
+ *o_ref,(char*)l_referenced, subsubcount,
+ detect_cycle || sub_type->cycle);
+
+ *(void**)dst=l_referenced;
+ VERB3("'%s' previously referenced at %p now at %p",
+ sub_type->name, *(void**)o_ref, l_referenced);
+
+ } else {
+ VERB2("NOT copying data previously referenced @%p (already done, @%p now)",
+ *(void**)o_ref, *(void**)n_ref);
+
+ *(void**)dst=*n_ref;
+
+ }