pmix_status_t pmix_bfrops_base_unpack_value(pmix_pointer_array_t *regtypes, pmix_buffer_t *buffer, void *dest, int32_t *num_vals, pmix_data_type_t type) { pmix_value_t *ptr; int32_t i, n; pmix_status_t ret; ptr = (pmix_value_t *) dest; n = *num_vals; for (i = 0; i < n; ++i) { /* unpack the type */ if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(regtypes, buffer, &ptr[i].type))) { PMIX_ERROR_LOG(ret); return ret; } /* unpack value */ if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_val(regtypes, buffer, &ptr[i])) ) { PMIX_ERROR_LOG(ret); return ret; } } return PMIX_SUCCESS; }
pmix_status_t pmix_bfrop_unpack_buffer(pmix_buffer_t *buffer, void *dst, int32_t *num_vals, pmix_data_type_t type) { pmix_status_t rc; pmix_data_type_t local_type; pmix_bfrop_type_info_t *info; pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_buffer( %p, %p, %lu, %d )\n", (void*)buffer, dst, (long unsigned int)*num_vals, (int)type); /** Unpack the declared data type */ if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) { if (PMIX_SUCCESS != (rc = pmix_bfrop_get_data_type(buffer, &local_type))) { return rc; } /* if the data types don't match, then return an error */ if (type != local_type) { pmix_output(0, "PMIX bfrop:unpack: got type %d when expecting type %d", local_type, type); return PMIX_ERR_PACK_MISMATCH; } } /* Lookup the unpack function for this type and call it */ if (NULL == (info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(&pmix_bfrop_types, type))) { return PMIX_ERR_UNPACK_FAILURE; } return info->odti_unpack_fn(buffer, dst, num_vals, type); }
static pmix_status_t pmix_bfrops_base_unpack_buffer(pmix_pointer_array_t *regtypes, pmix_buffer_t *buffer, void *dst, int32_t *num_vals, pmix_data_type_t type) { pmix_status_t rc; pmix_data_type_t local_type; pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output, "pmix_bfrops_base_unpack_buffer( %p, %p, %lu, %d )\n", (void*)buffer, dst, (long unsigned int)*num_vals, (int)type); /** Unpack the declared data type */ if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) { if (PMIX_SUCCESS != (rc = pmix_bfrop_get_data_type(regtypes, buffer, &local_type))) { PMIX_ERROR_LOG(rc); return rc; } /* if the data types don't match, then return an error */ if (type != local_type) { pmix_output(0, "PMIX bfrop:unpack: got type %d when expecting type %d", local_type, type); return PMIX_ERR_PACK_MISMATCH; } } PMIX_BFROPS_UNPACK_TYPE(rc, buffer, dst, num_vals, type, regtypes); return rc; }
/* * SIZE_T */ pmix_status_t pmix_bfrops_base_unpack_sizet(pmix_pointer_array_t *regtypes, pmix_buffer_t *buffer, void *dest, int32_t *num_vals, pmix_data_type_t type) { pmix_status_t ret; pmix_data_type_t remote_type; if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(regtypes, buffer, &remote_type))) { PMIX_ERROR_LOG(ret); return ret; } if (remote_type == BFROP_TYPE_SIZE_T) { /* fast path it if the sizes are the same */ /* Turn around and unpack the real type */ PMIX_BFROPS_UNPACK_TYPE(ret, buffer, dest, num_vals, BFROP_TYPE_SIZE_T, regtypes); if (PMIX_SUCCESS != ret) { PMIX_ERROR_LOG(ret); } } else { /* slow path - types are different sizes */ PMIX_BFROP_UNPACK_SIZE_MISMATCH(regtypes, size_t, remote_type, ret); } return ret; }
pmix_status_t pmix_bfrops_base_unpack_pdata(pmix_pointer_array_t *regtypes, pmix_buffer_t *buffer, void *dest, int32_t *num_vals, pmix_data_type_t type) { pmix_pdata_t *ptr; int32_t i, n, m; pmix_status_t ret; char *tmp; pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output, "pmix_bfrop_unpack: %d pdata", *num_vals); ptr = (pmix_pdata_t *) dest; n = *num_vals; for (i = 0; i < n; ++i) { PMIX_PDATA_CONSTRUCT(&ptr[i]); /* unpack the proc */ m=1; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ptr[i].proc, &m, PMIX_PROC, regtypes); if (PMIX_SUCCESS != ret) { return ret; } /* unpack key */ m=1; tmp = NULL; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &tmp, &m, PMIX_STRING, regtypes); if (PMIX_SUCCESS != ret) { return ret; } if (NULL == tmp) { PMIX_ERROR_LOG(PMIX_ERROR); return PMIX_ERROR; } pmix_strncpy(ptr[i].key, tmp, PMIX_MAX_KEYLEN); free(tmp); /* unpack value - since the value structure is statically-defined * instead of a pointer in this struct, we directly unpack it to * avoid the malloc */ if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(regtypes, buffer, &ptr[i].value.type))) { PMIX_ERROR_LOG(ret); return ret; } pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output, "pmix_bfrop_unpack: pdata type %d %s", ptr[i].value.type, ptr[i].value.data.string); m=1; if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_val(regtypes, buffer, &ptr[i].value))) { PMIX_ERROR_LOG(ret); return ret; } } return PMIX_SUCCESS; }
pmix_status_t pmix_bfrops_base_unpack_info(pmix_pointer_array_t *regtypes, pmix_buffer_t *buffer, void *dest, int32_t *num_vals, pmix_data_type_t type) { pmix_info_t *ptr; int32_t i, n, m; pmix_status_t ret; char *tmp; pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output, "pmix_bfrop_unpack: %d info", *num_vals); ptr = (pmix_info_t *) dest; n = *num_vals; for (i = 0; i < n; ++i) { memset(ptr[i].key, 0, sizeof(ptr[i].key)); memset(&ptr[i].value, 0, sizeof(pmix_value_t)); /* unpack key */ m=1; tmp = NULL; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &tmp, &m, PMIX_STRING, regtypes); if (PMIX_SUCCESS != ret) { PMIX_ERROR_LOG(ret); return ret; } if (NULL == tmp) { return PMIX_ERROR; } pmix_strncpy(ptr[i].key, tmp, PMIX_MAX_KEYLEN); free(tmp); /* unpack the directives */ m=1; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ptr[i].flags, &m, PMIX_INFO_DIRECTIVES, regtypes); if (PMIX_SUCCESS != ret) { return ret; } /* unpack value - since the value structure is statically-defined * instead of a pointer in this struct, we directly unpack it to * avoid the malloc */ if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(regtypes, buffer, &ptr[i].value.type))) { return ret; } pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output, "pmix_bfrop_unpack: info type %d", ptr[i].value.type); m=1; if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_val(regtypes, buffer, &ptr[i].value))) { return ret; } } return PMIX_SUCCESS; }
pmix_status_t pmix_bfrops_base_unpack_darray(pmix_pointer_array_t *regtypes, pmix_buffer_t *buffer, void *dest, int32_t *num_vals, pmix_data_type_t type) { pmix_data_array_t *ptr; int32_t i, n, m; pmix_status_t ret; pmix_data_type_t t; pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output, "pmix_bfrop_unpack: %d data arrays", *num_vals); ptr = (pmix_data_array_t *) dest; n = *num_vals; for (i = 0; i < n; ++i) { memset(&ptr[i], 0, sizeof(pmix_data_array_t)); /* unpack the type */ m=1; if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(regtypes, buffer, &ptr[i].type))) { return ret; } /* unpack the number of array elements */ m=1; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ptr[i].size, &m, PMIX_SIZE, regtypes); if (PMIX_SUCCESS != ret) { return ret; } if (0 == ptr[i].size || PMIX_UNDEF == ptr[i].type) { /* nothing else to do */ continue; } /* allocate storage for the array and unpack the array elements */ m = ptr[i].size; t = ptr[i].type; PMIX_DATA_ARRAY_CONSTRUCT(&ptr[i], m, t); if (NULL == ptr[i].array) { return PMIX_ERR_NOMEM; } PMIX_BFROPS_UNPACK_TYPE(ret, buffer, ptr[i].array, &m, t, regtypes); if (PMIX_SUCCESS != ret) { return ret; } } return PMIX_SUCCESS; }
pmix_status_t pmix_bfrop_unpack_value(pmix_buffer_t *buffer, void *dest, int32_t *num_vals, pmix_data_type_t type) { pmix_value_t *ptr; int32_t i, n; pmix_status_t ret; ptr = (pmix_value_t *) dest; n = *num_vals; for (i = 0; i < n; ++i) { /* unpack the type */ if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &ptr[i].type))) { return ret; } /* unpack value */ if (PMIX_SUCCESS != (ret = unpack_val(buffer, &ptr[i])) ) { return ret; } } return PMIX_SUCCESS; }
/* * PID_T */ pmix_status_t pmix_bfrop_unpack_pid(pmix_buffer_t *buffer, void *dest, int32_t *num_vals, pmix_data_type_t type) { pmix_status_t ret; pmix_data_type_t remote_type; if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &remote_type))) { return ret; } if (remote_type == BFROP_TYPE_PID_T) { /* fast path it if the sizes are the same */ /* Turn around and unpack the real type */ if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, dest, num_vals, BFROP_TYPE_PID_T))) { } } else { /* slow path - types are different sizes */ UNPACK_SIZE_MISMATCH(pid_t, remote_type, ret); } return ret; }
pmix_status_t pmix_bfrop_unpack(pmix_buffer_t *buffer, void *dst, int32_t *num_vals, pmix_data_type_t type) { pmix_status_t rc, ret; int32_t local_num, n=1; pmix_data_type_t local_type; /* check for error */ if (NULL == buffer || NULL == dst || NULL == num_vals) { return PMIX_ERR_BAD_PARAM; } /* if user provides a zero for num_vals, then there is no storage allocated * so return an appropriate error */ if (0 == *num_vals) { pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack: inadequate space ( %p, %p, %lu, %d )\n", (void*)buffer, dst, (long unsigned int)*num_vals, (int)type); return PMIX_ERR_UNPACK_INADEQUATE_SPACE; } /** Unpack the declared number of values * REMINDER: it is possible that the buffer is corrupted and that * the BFROP will *think* there is a proper int32_t variable at the * beginning of the unpack region - but that the value is bogus (e.g., just * a byte field in a string array that so happens to have a value that * matches the int32_t data type flag). Therefore, this error check is * NOT completely safe. This is true for ALL unpack functions, not just * int32_t as used here. */ if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) { if (PMIX_SUCCESS != (rc = pmix_bfrop_get_data_type(buffer, &local_type))) { *num_vals = 0; /* don't error log here as the user may be unpacking past * the end of the buffer, which isn't necessarily an error */ return rc; } if (PMIX_INT32 != local_type) { /* if the length wasn't first, then error */ *num_vals = 0; return PMIX_ERR_UNPACK_FAILURE; } } n=1; if (PMIX_SUCCESS != (rc = pmix_bfrop_unpack_int32(buffer, &local_num, &n, PMIX_INT32))) { *num_vals = 0; /* don't error log here as the user may be unpacking past * the end of the buffer, which isn't necessarily an error */ return rc; } pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack: found %d values for %d provided storage", local_num, *num_vals); /** if the storage provided is inadequate, set things up * to unpack as much as we can and to return an error code * indicating that everything was not unpacked - the buffer * is left in a state where it can not be further unpacked. */ if (local_num > *num_vals) { local_num = *num_vals; pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack: inadequate space ( %p, %p, %lu, %d )\n", (void*)buffer, dst, (long unsigned int)*num_vals, (int)type); ret = PMIX_ERR_UNPACK_INADEQUATE_SPACE; } else { /** enough or more than enough storage */ *num_vals = local_num; /** let the user know how many we actually unpacked */ ret = PMIX_SUCCESS; } /** Unpack the value(s) */ if (PMIX_SUCCESS != (rc = pmix_bfrop_unpack_buffer(buffer, dst, &local_num, type))) { *num_vals = 0; ret = rc; } return ret; }