/* * 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_VALUE */ static pmix_status_t unpack_val(pmix_buffer_t *buffer, pmix_value_t *val) { int32_t m; pmix_status_t ret; m = 1; switch (val->type) { case PMIX_UNDEF: break; case PMIX_BOOL: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.flag, &m, PMIX_BOOL))) { return ret; } break; case PMIX_BYTE: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.byte, &m, PMIX_BYTE))) { return ret; } break; case PMIX_STRING: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.string, &m, PMIX_STRING))) { return ret; } break; case PMIX_SIZE: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.size, &m, PMIX_SIZE))) { return ret; } break; case PMIX_PID: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.pid, &m, PMIX_PID))) { return ret; } break; case PMIX_INT: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.integer, &m, PMIX_INT))) { return ret; } break; case PMIX_INT8: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int8, &m, PMIX_INT8))) { return ret; } break; case PMIX_INT16: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int16, &m, PMIX_INT16))) { return ret; } break; case PMIX_INT32: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int32, &m, PMIX_INT32))) { return ret; } break; case PMIX_INT64: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int64, &m, PMIX_INT64))) { return ret; } break; case PMIX_UINT: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint, &m, PMIX_UINT))) { return ret; } break; case PMIX_UINT8: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint8, &m, PMIX_UINT8))) { return ret; } break; case PMIX_UINT16: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint16, &m, PMIX_UINT16))) { return ret; } break; case PMIX_UINT32: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint32, &m, PMIX_UINT32))) { return ret; } break; case PMIX_UINT64: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint64, &m, PMIX_UINT64))) { return ret; } break; case PMIX_FLOAT: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.fval, &m, PMIX_FLOAT))) { return ret; } break; case PMIX_DOUBLE: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.dval, &m, PMIX_DOUBLE))) { return ret; } break; case PMIX_TIMEVAL: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.tv, &m, PMIX_TIMEVAL))) { return ret; } break; case PMIX_TIME: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.time, &m, PMIX_TIME))) { return ret; } break; case PMIX_STATUS: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.status, &m, PMIX_STATUS))) { return ret; } break; case PMIX_PROC: /* this field is now a pointer, so we must allocate storage for it */ PMIX_PROC_CREATE(val->data.proc, m); if (NULL == val->data.proc) { return PMIX_ERR_NOMEM; } if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, val->data.proc, &m, PMIX_PROC))) { return ret; } break; case PMIX_PROC_RANK: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.rank, &m, PMIX_PROC_RANK))) { return ret; } break; case PMIX_BYTE_OBJECT: case PMIX_COMPRESSED_STRING: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.bo, &m, PMIX_BYTE_OBJECT))) { return ret; } break; case PMIX_PERSIST: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.proc, &m, PMIX_PROC))) { return ret; } break; case PMIX_POINTER: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.ptr, &m, PMIX_POINTER))) { return ret; } break; case PMIX_SCOPE: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.scope, &m, PMIX_SCOPE))) { return ret; } break; case PMIX_DATA_RANGE: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.range, &m, PMIX_DATA_RANGE))) { return ret; } break; case PMIX_PROC_STATE: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.state, &m, PMIX_PROC_STATE))) { return ret; } break; case PMIX_PROC_INFO: /* this is now a pointer, so allocate storage for it */ PMIX_PROC_INFO_CREATE(val->data.pinfo, 1); if (NULL == val->data.pinfo) { return PMIX_ERR_NOMEM; } if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, val->data.pinfo, &m, PMIX_PROC_INFO))) { return ret; } break; case PMIX_DATA_ARRAY: /* this is now a pointer, so allocate storage for it */ val->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t)); if (NULL == val->data.darray) { return PMIX_ERR_NOMEM; } if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, val->data.darray, &m, PMIX_DATA_ARRAY))) { return ret; } break; case PMIX_QUERY: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, val->data.darray, &m, PMIX_QUERY))) { return ret; } break; /**** DEPRECATED ****/ case PMIX_INFO_ARRAY: /* this field is now a pointer, so we must allocate storage for it */ val->data.array = (pmix_info_array_t*)malloc(sizeof(pmix_info_array_t)); if (NULL == val->data.array) { return PMIX_ERR_NOMEM; } if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, val->data.array, &m, PMIX_INFO_ARRAY))) { return ret; } break; /********************/ default: pmix_output(0, "UNPACK-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)val->type); return PMIX_ERROR; } return PMIX_SUCCESS; }
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; }
pmix_status_t pmix_bfrop_unpack_darray(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; size_t nbytes; pmix_output_verbose(20, pmix_globals.debug_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_unpack_datatype(buffer, &ptr[i].type, &m, PMIX_DATA_TYPE))) { return ret; } /* unpack the number of array elements */ m=1; if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_sizet(buffer, &ptr[i].size, &m, PMIX_SIZE))) { 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; switch(ptr[i].type) { case PMIX_BOOL: nbytes = sizeof(bool); break; case PMIX_BYTE: case PMIX_INT8: case PMIX_UINT8: nbytes = sizeof(int8_t); break; case PMIX_INT16: case PMIX_UINT16: nbytes = sizeof(int16_t); break; case PMIX_INT32: case PMIX_UINT32: nbytes = sizeof(int32_t); break; case PMIX_INT64: case PMIX_UINT64: nbytes = sizeof(int64_t); break; case PMIX_STRING: nbytes = sizeof(char*); break; case PMIX_SIZE: nbytes = sizeof(size_t); break; case PMIX_PID: nbytes = sizeof(pid_t); break; case PMIX_INT: case PMIX_UINT: nbytes = sizeof(int); break; case PMIX_FLOAT: nbytes = sizeof(float); break; case PMIX_DOUBLE: nbytes = sizeof(double); break; case PMIX_TIMEVAL: nbytes = sizeof(struct timeval); break; case PMIX_TIME: nbytes = sizeof(time_t); break; case PMIX_STATUS: nbytes = sizeof(pmix_status_t); break; case PMIX_INFO: nbytes = sizeof(pmix_info_t); break; case PMIX_PROC: nbytes = sizeof(pmix_proc_t); break; case PMIX_BYTE_OBJECT: case PMIX_COMPRESSED_STRING: nbytes = sizeof(pmix_byte_object_t); break; case PMIX_PERSIST: nbytes = sizeof(pmix_persistence_t); break; case PMIX_SCOPE: nbytes = sizeof(pmix_scope_t); break; case PMIX_DATA_RANGE: nbytes = sizeof(pmix_data_range_t); break; case PMIX_PROC_STATE: nbytes = sizeof(pmix_proc_state_t); break; case PMIX_PROC_INFO: nbytes = sizeof(pmix_proc_info_t); break; case PMIX_QUERY: nbytes = sizeof(pmix_query_t); default: return PMIX_ERR_NOT_SUPPORTED; } if (NULL == (ptr[i].array = malloc(m * nbytes))) { return PMIX_ERR_NOMEM; } if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, ptr[i].array, &m, ptr[i].type))) { return ret; } } return PMIX_SUCCESS; }
/* * PMIX_VALUE */ static int unpack_val(pmix_buffer_t *buffer, pmix_value_t *val) { int ret, m; m = 1; switch (val->type) { case PMIX_BOOL: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.flag, &m, PMIX_BOOL))) { return ret; } break; case PMIX_BYTE: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.byte, &m, PMIX_BYTE))) { return ret; } break; case PMIX_STRING: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.string, &m, PMIX_STRING))) { return ret; } break; case PMIX_SIZE: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.size, &m, PMIX_SIZE))) { return ret; } break; case PMIX_PID: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.pid, &m, PMIX_PID))) { return ret; } break; case PMIX_INT: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.integer, &m, PMIX_INT))) { return ret; } break; case PMIX_INT8: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int8, &m, PMIX_INT8))) { return ret; } break; case PMIX_INT16: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int16, &m, PMIX_INT16))) { return ret; } break; case PMIX_INT32: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int32, &m, PMIX_INT32))) { return ret; } break; case PMIX_INT64: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int64, &m, PMIX_INT64))) { return ret; } break; case PMIX_UINT: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint, &m, PMIX_UINT))) { return ret; } break; case PMIX_UINT8: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint8, &m, PMIX_UINT8))) { return ret; } break; case PMIX_UINT16: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint16, &m, PMIX_UINT16))) { return ret; } break; case PMIX_UINT32: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint32, &m, PMIX_UINT32))) { return ret; } break; case PMIX_UINT64: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint64, &m, PMIX_UINT64))) { return ret; } break; case PMIX_FLOAT: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.fval, &m, PMIX_FLOAT))) { return ret; } break; case PMIX_DOUBLE: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.dval, &m, PMIX_DOUBLE))) { return ret; } break; case PMIX_TIMEVAL: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.tv, &m, PMIX_TIMEVAL))) { return ret; } break; case PMIX_INFO_ARRAY: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.array, &m, PMIX_INFO_ARRAY))) { return ret; } break; case PMIX_BYTE_OBJECT: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.bo, &m, PMIX_BYTE_OBJECT))) { return ret; } break; default: pmix_output(0, "UNPACK-PMIX-VALUE: UNSUPPORTED TYPE"); return PMIX_ERROR; } return PMIX_SUCCESS; }