+ ref_data = type->category.ref_data;
+
+ /* Get the referenced type locally or from peer */
+ sub_type = ref_data.type;
+ if (sub_type == NULL) {
+ int ref_code;
+ TRY(gras_dd_recv_int(sock, r_arch, &ref_code));
+ TRY(gras_datadesc_by_id(ref_code, &sub_type));
+ }
+
+ /* Get the actual value of the pointer for cycle handling */
+ if (!pointer_type) {
+ pointer_type = gras_datadesc_by_name("data pointer");
+ xbt_assert(pointer_type);
+ }
+
+ r_ref = xbt_malloc(pointer_type->size[r_arch]);
+
+ TRY(gras_trp_chunk_recv(sock, (char*)r_ref,
+ pointer_type->size[r_arch]));
+
+ /* Receive the pointed data only if not already sent */
+ if (gras_dd_is_r_null(r_ref, pointer_type->size[r_arch])) {
+ VERB1("Not receiving data remotely referenced @%p since it's NULL",
+ *(void **)r_ref);
+ *(void**)l_data = NULL;
+ free(r_ref);
+ break;
+ }
+
+ errcode = detect_cycle
+ ? xbt_dict_get_ext(refs,
+ (char*)r_ref, pointer_type->size[r_arch],
+ (void**)&l_ref)
+ : mismatch_error;
+
+ if (errcode == mismatch_error) {
+ int subsubcount = 0;
+ void *l_referenced=NULL;
+
+ VERB2("Receiving a ref to '%s', remotely @%p",
+ sub_type->name, *(void**)r_ref);
+ if (sub_type->category_code == e_gras_datadesc_type_cat_array) {
+ /* Damn. Reference to a dynamic array. Allocating the size for it
+ is more complicated */
+ gras_dd_cat_array_t array_data = sub_type->category.array_data;
+ gras_datadesc_type_t subsub_type;
+
+ subsubcount = array_data.fixed_size;
+ if (subsubcount == 0)
+ TRY(gras_dd_recv_int(sock, r_arch, &subsubcount));
+
+ subsub_type = array_data.type;
+
+
+ TRY(gras_dd_alloc_ref(refs,
+ subsub_type->size[GRAS_THISARCH] * subsubcount,
+ r_ref,pointer_type->size[r_arch],
+ (char**)&l_referenced,
+ detect_cycle));
+ } else {
+ TRY(gras_dd_alloc_ref(refs,sub_type->size[GRAS_THISARCH],
+ r_ref,pointer_type->size[r_arch],
+ (char**)&l_referenced,
+ detect_cycle));
+ }
+
+ TRY(gras_datadesc_recv_rec(sock,state,refs, sub_type,
+ r_arch,r_ref,pointer_type->size[r_arch],
+ (char*)l_referenced, subsubcount,
+ detect_cycle || sub_type->cycle));
+
+ *(void**)l_data=l_referenced;
+ VERB3("'%s' remotely referenced at %p locally at %p",
+ sub_type->name, *(void**)r_ref, l_referenced);
+
+ } else if (errcode == no_error) {
+ VERB2("NOT receiving data remotely referenced @%p (already done, @%p here)",
+ *(void**)r_ref, *(void**)l_ref);
+
+ *(void**)l_data=*l_ref;
+
+ } else {
+ return errcode;
+ }
+ free(r_ref);
+ break;
+ }
+
+ case e_gras_datadesc_type_cat_array: {
+ gras_dd_cat_array_t array_data;
+ int count;
+ char *ptr;
+ long int elm_size;
+
+ array_data = type->category.array_data;
+ /* determine element count locally, or from caller, or from peer */
+ count = array_data.fixed_size;
+ if (count == 0)
+ count = subsize;
+ if (count == 0)
+ TRY(gras_dd_recv_int(sock, r_arch, &count));
+ if (count == 0)
+ RAISE1(mismatch_error,
+ "Invalid (=0) array size for type %s",type->name);
+
+ /* receive the content */
+ sub_type = array_data.type;
+ if (sub_type->category_code == e_gras_datadesc_type_cat_scalar) {
+ VERB1("Array of %d scalars, get it in one shoot", count);
+ if (sub_type->aligned_size[GRAS_THISARCH] >=
+ sub_type->aligned_size[r_arch]) {
+ TRY(gras_trp_chunk_recv(sock, (char*)l_data,
+ sub_type->aligned_size[r_arch] * count));
+ if (r_arch != GRAS_THISARCH)
+ TRY(gras_dd_convert_elm(sub_type,count,r_arch, l_data,l_data));
+ } else {
+ ptr = xbt_malloc(sub_type->aligned_size[r_arch] * count);
+
+ TRY(gras_trp_chunk_recv(sock, (char*)ptr,
+ sub_type->size[r_arch] * count));
+ if (r_arch != GRAS_THISARCH)
+ TRY(gras_dd_convert_elm(sub_type,count,r_arch, ptr,l_data));
+ free(ptr);
+ }
+ } else if (sub_type->category_code == e_gras_datadesc_type_cat_array &&
+ sub_type->category.array_data.fixed_size > 0 &&
+ sub_type->category.array_data.type->category_code == e_gras_datadesc_type_cat_scalar) {
+ gras_datadesc_type_t subsub_type;
+ array_data = sub_type->category.array_data;
+ subsub_type = array_data.type;
+
+ VERB1("Array of %d fixed array of scalars, get it in one shot",count);
+ if (subsub_type->aligned_size[GRAS_THISARCH] >=
+ subsub_type->aligned_size[r_arch]) {
+ TRY(gras_trp_chunk_recv(sock, (char*)l_data,
+ subsub_type->aligned_size[r_arch] * count *
+ array_data.fixed_size));
+ if (r_arch != GRAS_THISARCH)
+ TRY(gras_dd_convert_elm(subsub_type,count*array_data.fixed_size,r_arch, l_data,l_data));
+ } else {
+ ptr = xbt_malloc(subsub_type->aligned_size[r_arch] * count*array_data.fixed_size);
+
+ TRY(gras_trp_chunk_recv(sock, (char*)ptr,
+ subsub_type->size[r_arch] * count*array_data.fixed_size));
+ if (r_arch != GRAS_THISARCH)
+ TRY(gras_dd_convert_elm(subsub_type,count*array_data.fixed_size,r_arch, ptr,l_data));
+ free(ptr);
+ }
+
+
+ } else {
+ /* not scalar content, get it recursively (may contain pointers) */
+ elm_size = sub_type->aligned_size[GRAS_THISARCH];
+ VERB2("Receive a %d-long array of %s",count, sub_type->name);
+
+ ptr = l_data;
+ for (cpt=0; cpt<count; cpt++) {
+ TRY(gras_datadesc_recv_rec(sock,state,refs, sub_type,
+ r_arch, NULL, 0, ptr,-1,
+ detect_cycle || sub_type->cycle));
+
+ ptr += elm_size;
+ }
+ }