root/opal/mca/pmix/pmix4x/pmix/src/mca/bfrops/v20/unpack.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pmix20_bfrop_unpack
  2. pmix20_bfrop_unpack_buffer
  3. pmix20_bfrop_unpack_bool
  4. pmix20_bfrop_unpack_int
  5. pmix20_bfrop_unpack_sizet
  6. pmix20_bfrop_unpack_pid
  7. pmix20_bfrop_unpack_byte
  8. pmix20_bfrop_unpack_int16
  9. pmix20_bfrop_unpack_int32
  10. pmix20_bfrop_unpack_datatype
  11. pmix20_bfrop_unpack_int64
  12. pmix20_bfrop_unpack_string
  13. pmix20_bfrop_unpack_float
  14. pmix20_bfrop_unpack_double
  15. pmix20_bfrop_unpack_timeval
  16. pmix20_bfrop_unpack_time
  17. pmix20_bfrop_unpack_status
  18. unpack_val
  19. pmix20_bfrop_unpack_value
  20. pmix20_bfrop_unpack_info
  21. pmix20_bfrop_unpack_pdata
  22. pmix20_bfrop_unpack_buf
  23. pmix20_bfrop_unpack_proc
  24. pmix20_bfrop_unpack_app
  25. pmix20_bfrop_unpack_kval
  26. pmix20_bfrop_unpack_modex
  27. pmix20_bfrop_unpack_persist
  28. pmix20_bfrop_unpack_scope
  29. pmix20_bfrop_unpack_range
  30. pmix20_bfrop_unpack_cmd
  31. pmix20_bfrop_unpack_infodirs
  32. pmix20_bfrop_unpack_bo
  33. pmix20_bfrop_unpack_ptr
  34. pmix20_bfrop_unpack_pstate
  35. pmix20_bfrop_unpack_pinfo
  36. pmix20_bfrop_unpack_darray
  37. pmix20_bfrop_unpack_rank
  38. pmix20_bfrop_unpack_query
  39. pmix20_bfrop_unpack_alloc_directive
  40. pmix20_bfrop_unpack_array

   1 /*
   2  * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2006 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2012      Los Alamos National Security, Inc.  All rights reserved.
  13  * Copyright (c) 2014-2019 Intel, Inc.  All rights reserved.
  14  * Copyright (c) 2015-2019 Research Organization for Information Science
  15  *                         and Technology (RIST).  All rights reserved.
  16  * Copyright (c) 2016-2019 Mellanox Technologies, Inc.
  17  *                         All rights reserved.
  18  * Copyright (c) 2016      IBM Corporation.  All rights reserved.
  19  * $COPYRIGHT$
  20  *
  21  * Additional copyrights may follow
  22  *
  23  * $HEADER$
  24  */
  25 
  26 #include <src/include/pmix_config.h>
  27 
  28 #include "src/util/argv.h"
  29 #include "src/util/error.h"
  30 #include "src/util/output.h"
  31 #include "src/mca/bfrops/base/base.h"
  32 #include "bfrop_pmix20.h"
  33 #include "internal.h"
  34 
  35 pmix_status_t pmix20_bfrop_unpack(pmix_buffer_t *buffer,
  36                                   void *dst, int32_t *num_vals,
  37                                   pmix_data_type_t type)
  38  {
  39     pmix_status_t rc, ret;
  40     int32_t local_num, n=1;
  41     pmix_data_type_t local_type;
  42     pmix_pointer_array_t *regtypes = &mca_bfrops_v20_component.types;
  43 
  44     /* check for error */
  45     if (NULL == buffer || NULL == dst || NULL == num_vals) {
  46         return PMIX_ERR_BAD_PARAM;
  47     }
  48 
  49     /* if user provides a zero for num_vals, then there is no storage allocated
  50      * so return an appropriate error
  51      */
  52      if (0 == *num_vals) {
  53         pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
  54                             "pmix20_bfrop_unpack: inadequate space ( %p, %p, %lu, %d )\n",
  55                             (void*)buffer, dst, (long unsigned int)*num_vals, (int)type);
  56         return PMIX_ERR_UNPACK_INADEQUATE_SPACE;
  57     }
  58 
  59     /** Unpack the declared number of values
  60      * REMINDER: it is possible that the buffer is corrupted and that
  61      * the BFROP will *think* there is a proper int32_t variable at the
  62      * beginning of the unpack region - but that the value is bogus (e.g., just
  63      * a byte field in a string array that so happens to have a value that
  64      * matches the int32_t data type flag). Therefore, this error check is
  65      * NOT completely safe. This is true for ALL unpack functions, not just
  66      * int32_t as used here.
  67      */
  68      if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) {
  69         if (PMIX_SUCCESS != (rc = pmix20_bfrop_get_data_type(regtypes, buffer, &local_type))) {
  70             *num_vals = 0;
  71             /* don't error log here as the user may be unpacking past
  72              * the end of the buffer, which isn't necessarily an error */
  73             return rc;
  74         }
  75         if (PMIX_INT32 != local_type) { /* if the length wasn't first, then error */
  76             *num_vals = 0;
  77             return PMIX_ERR_UNPACK_FAILURE;
  78         }
  79     }
  80 
  81     n=1;
  82     PMIX_BFROPS_UNPACK_TYPE(rc, buffer, &local_num, &n, PMIX_INT32, regtypes);
  83     if (PMIX_SUCCESS != rc) {
  84         *num_vals = 0;
  85             /* don't error log here as the user may be unpacking past
  86              * the end of the buffer, which isn't necessarily an error */
  87         return rc;
  88     }
  89 
  90     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
  91                         "pmix20_bfrop_unpack: found %d values for %d provided storage",
  92                         local_num, *num_vals);
  93 
  94     /** if the storage provided is inadequate, set things up
  95      * to unpack as much as we can and to return an error code
  96      * indicating that everything was not unpacked - the buffer
  97      * is left in a state where it can not be further unpacked.
  98      */
  99      if (local_num > *num_vals) {
 100         local_num = *num_vals;
 101         pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 102                             "pmix20_bfrop_unpack: inadequate space ( %p, %p, %lu, %d )\n",
 103                             (void*)buffer, dst, (long unsigned int)*num_vals, (int)type);
 104         ret = PMIX_ERR_UNPACK_INADEQUATE_SPACE;
 105     } else {  /** enough or more than enough storage */
 106         *num_vals = local_num;  /** let the user know how many we actually unpacked */
 107         ret = PMIX_SUCCESS;
 108     }
 109 
 110     /** Unpack the value(s) */
 111     if (PMIX_SUCCESS != (rc = pmix20_bfrop_unpack_buffer(regtypes, buffer, dst, &local_num, type))) {
 112         *num_vals = 0;
 113         ret = rc;
 114     }
 115 
 116     return ret;
 117 }
 118 
 119 pmix_status_t pmix20_bfrop_unpack_buffer(pmix_pointer_array_t *regtypes,
 120                                          pmix_buffer_t *buffer, void *dst, int32_t *num_vals,
 121                                          pmix_data_type_t type)
 122 {
 123     pmix_status_t rc;
 124     pmix_data_type_t local_type, v20type;
 125 
 126     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 127                         "pmix20_bfrop_unpack_buffer( %p, %p, %lu, %d )\n",
 128                         (void*)buffer, dst, (long unsigned int)*num_vals, (int)type);
 129 
 130     /* some v20 types are simply declared differently */
 131     switch (type) {
 132         case PMIX_COMMAND:
 133             v20type = PMIX_UINT32;
 134             break;
 135         default:
 136             v20type = type;
 137     }
 138 
 139     /** Unpack the declared data type */
 140     if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) {
 141         if (PMIX_SUCCESS != (rc = pmix20_bfrop_get_data_type(regtypes, buffer, &local_type))) {
 142             return rc;
 143         }
 144         /* if the data types don't match, then return an error */
 145         if (v20type != local_type) {
 146             pmix_output(0, "PMIX bfrop:unpack: got type %d when expecting type %d", local_type, v20type);
 147             return PMIX_ERR_PACK_MISMATCH;
 148         }
 149     }
 150     PMIX_BFROPS_UNPACK_TYPE(rc, buffer, dst, num_vals, v20type, regtypes);
 151     return rc;
 152 }
 153 
 154 
 155 /* UNPACK GENERIC SYSTEM TYPES */
 156 
 157 /*
 158  * BOOL
 159  */
 160 pmix_status_t pmix20_bfrop_unpack_bool(pmix_pointer_array_t *regtypes,
 161                                        pmix_buffer_t *buffer, void *dest,
 162                                        int32_t *num_vals, pmix_data_type_t type)
 163  {
 164     int32_t i;
 165     uint8_t *src;
 166     bool *dst;
 167 
 168     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 169                         "pmix20_bfrop_unpack_bool * %d\n", (int)*num_vals);
 170     /* check to see if there's enough data in buffer */
 171     if (pmix_bfrop_too_small(buffer, *num_vals)) {
 172         return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER;
 173     }
 174 
 175     /* unpack the data */
 176     src = (uint8_t*)buffer->unpack_ptr;
 177     dst = (bool*)dest;
 178 
 179     for (i=0; i < *num_vals; i++) {
 180         if (src[i]) {
 181             dst[i] = true;
 182         } else {
 183             dst[i] = false;
 184         }
 185     }
 186 
 187     /* update buffer pointer */
 188     buffer->unpack_ptr += *num_vals;
 189 
 190     return PMIX_SUCCESS;
 191 }
 192 
 193 /*
 194  * INT
 195  */
 196 pmix_status_t pmix20_bfrop_unpack_int(pmix_pointer_array_t *regtypes,
 197                                       pmix_buffer_t *buffer, void *dest,
 198                                       int32_t *num_vals, pmix_data_type_t type)
 199  {
 200     pmix_status_t ret;
 201     pmix_data_type_t remote_type;
 202 
 203     if (PMIX_SUCCESS != (ret = pmix20_bfrop_get_data_type(regtypes, buffer, &remote_type))) {
 204         return ret;
 205     }
 206 
 207     if (remote_type == BFROP_TYPE_INT) {
 208         /* fast path it if the sizes are the same */
 209         /* Turn around and unpack the real type */
 210         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, dest,
 211                                                               num_vals, BFROP_TYPE_INT))) {
 212         }
 213     } else {
 214         /* slow path - types are different sizes */
 215         PMIX_BFROP_UNPACK_SIZE_MISMATCH(regtypes, int, remote_type, ret);
 216     }
 217 
 218     return ret;
 219 }
 220 
 221 /*
 222  * SIZE_T
 223  */
 224 pmix_status_t pmix20_bfrop_unpack_sizet(pmix_pointer_array_t *regtypes,
 225                                         pmix_buffer_t *buffer, void *dest,
 226                                         int32_t *num_vals, pmix_data_type_t type)
 227  {
 228     pmix_status_t ret;
 229     pmix_data_type_t remote_type;
 230 
 231     if (PMIX_SUCCESS != (ret = pmix20_bfrop_get_data_type(regtypes, buffer, &remote_type))) {
 232         return ret;
 233     }
 234 
 235     if (remote_type == BFROP_TYPE_SIZE_T) {
 236         /* fast path it if the sizes are the same */
 237         /* Turn around and unpack the real type */
 238         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer,
 239                                                               dest, num_vals, BFROP_TYPE_SIZE_T))) {
 240         }
 241     } else {
 242         /* slow path - types are different sizes */
 243         PMIX_BFROP_UNPACK_SIZE_MISMATCH(regtypes, size_t, remote_type, ret);
 244     }
 245 
 246     return ret;
 247 }
 248 
 249 /*
 250  * PID_T
 251  */
 252 pmix_status_t pmix20_bfrop_unpack_pid(pmix_pointer_array_t *regtypes,
 253                                       pmix_buffer_t *buffer, void *dest,
 254                                       int32_t *num_vals, pmix_data_type_t type)
 255  {
 256     pmix_status_t ret;
 257     pmix_data_type_t remote_type;
 258 
 259     if (PMIX_SUCCESS != (ret = pmix20_bfrop_get_data_type(regtypes, buffer, &remote_type))) {
 260         return ret;
 261     }
 262 
 263     if (remote_type == BFROP_TYPE_PID_T) {
 264         /* fast path it if the sizes are the same */
 265         /* Turn around and unpack the real type */
 266         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, dest, num_vals, BFROP_TYPE_PID_T))) {
 267         }
 268     } else {
 269         /* slow path - types are different sizes */
 270         PMIX_BFROP_UNPACK_SIZE_MISMATCH(regtypes, pid_t, remote_type, ret);
 271     }
 272 
 273     return ret;
 274 }
 275 
 276 
 277 /* UNPACK FUNCTIONS FOR NON-GENERIC SYSTEM TYPES */
 278 
 279 /*
 280  * BYTE, CHAR, INT8
 281  */
 282 pmix_status_t pmix20_bfrop_unpack_byte(pmix_pointer_array_t *regtypes,
 283                                        pmix_buffer_t *buffer, void *dest,
 284                                        int32_t *num_vals, pmix_data_type_t type)
 285  {
 286     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 287                         "pmix20_bfrop_unpack_byte * %d\n", (int)*num_vals);
 288     /* check to see if there's enough data in buffer */
 289     if (pmix_bfrop_too_small(buffer, *num_vals)) {
 290         return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER;
 291     }
 292 
 293     /* unpack the data */
 294     memcpy(dest, buffer->unpack_ptr, *num_vals);
 295 
 296     /* update buffer pointer */
 297     buffer->unpack_ptr += *num_vals;
 298 
 299     return PMIX_SUCCESS;
 300 }
 301 
 302 pmix_status_t pmix20_bfrop_unpack_int16(pmix_pointer_array_t *regtypes,
 303                                         pmix_buffer_t *buffer, void *dest,
 304                                         int32_t *num_vals, pmix_data_type_t type)
 305 {
 306     int32_t i;
 307     uint16_t tmp, *desttmp = (uint16_t*) dest;
 308 
 309     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 310                         "pmix20_bfrop_unpack_int16 * %d\n", (int)*num_vals);
 311     /* check to see if there's enough data in buffer */
 312     if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(tmp))) {
 313         return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER;
 314     }
 315 
 316     /* unpack the data */
 317     for (i = 0; i < (*num_vals); ++i) {
 318         memcpy( &(tmp), buffer->unpack_ptr, sizeof(tmp) );
 319         tmp = pmix_ntohs(tmp);
 320         memcpy(&desttmp[i], &tmp, sizeof(tmp));
 321         buffer->unpack_ptr += sizeof(tmp);
 322     }
 323 
 324     return PMIX_SUCCESS;
 325 }
 326 
 327 pmix_status_t pmix20_bfrop_unpack_int32(pmix_pointer_array_t *regtypes,
 328                                         pmix_buffer_t *buffer, void *dest,
 329                                         int32_t *num_vals, pmix_data_type_t type)
 330 {
 331     int32_t i;
 332     uint32_t tmp, *desttmp = (uint32_t*) dest;
 333 
 334     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 335                         "pmix20_bfrop_unpack_int32 * %d\n", (int)*num_vals);
 336     /* check to see if there's enough data in buffer */
 337     if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(tmp))) {
 338         return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER;
 339     }
 340 
 341     /* unpack the data */
 342     for (i = 0; i < (*num_vals); ++i) {
 343         memcpy( &(tmp), buffer->unpack_ptr, sizeof(tmp) );
 344         tmp = ntohl(tmp);
 345         memcpy(&desttmp[i], &tmp, sizeof(tmp));
 346         buffer->unpack_ptr += sizeof(tmp);
 347     }
 348 
 349     return PMIX_SUCCESS;
 350 }
 351 
 352 pmix_status_t pmix20_bfrop_unpack_datatype(pmix_pointer_array_t *regtypes,
 353                                            pmix_buffer_t *buffer, void *dest,
 354                                            int32_t *num_vals, pmix_data_type_t type)
 355 {
 356     pmix_status_t ret;
 357 
 358     PMIX_BFROPS_UNPACK_TYPE(ret, buffer, dest, num_vals, PMIX_INT16, regtypes);
 359     return ret;
 360 }
 361 
 362 pmix_status_t pmix20_bfrop_unpack_int64(pmix_pointer_array_t *regtypes,
 363                                         pmix_buffer_t *buffer, void *dest,
 364                                         int32_t *num_vals, pmix_data_type_t type)
 365 {
 366     int32_t i;
 367     uint64_t tmp, *desttmp = (uint64_t*) dest;
 368 
 369     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 370                         "pmix20_bfrop_unpack_int64 * %d\n", (int)*num_vals);
 371     /* check to see if there's enough data in buffer */
 372     if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(tmp))) {
 373         return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER;
 374     }
 375 
 376     /* unpack the data */
 377     for (i = 0; i < (*num_vals); ++i) {
 378         memcpy( &(tmp), buffer->unpack_ptr, sizeof(tmp) );
 379         tmp = pmix_ntoh64(tmp);
 380         memcpy(&desttmp[i], &tmp, sizeof(tmp));
 381         buffer->unpack_ptr += sizeof(tmp);
 382     }
 383 
 384     return PMIX_SUCCESS;
 385 }
 386 
 387 pmix_status_t pmix20_bfrop_unpack_string(pmix_pointer_array_t *regtypes,
 388                                          pmix_buffer_t *buffer, void *dest,
 389                                          int32_t *num_vals, pmix_data_type_t type)
 390 {
 391     pmix_status_t ret;
 392     int32_t i, len, n=1;
 393     char **sdest = (char**) dest;
 394 
 395     for (i = 0; i < (*num_vals); ++i) {
 396         PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &len, &n, PMIX_INT32, regtypes);
 397         if (PMIX_SUCCESS != ret) {
 398             return ret;
 399         }
 400         if (0 ==  len) {   /* zero-length string - unpack the NULL */
 401             sdest[i] = NULL;
 402         } else {
 403             sdest[i] = (char*)malloc(len);
 404             if (NULL == sdest[i]) {
 405                 return PMIX_ERR_OUT_OF_RESOURCE;
 406             }
 407             PMIX_BFROPS_UNPACK_TYPE(ret, buffer, sdest[i], &len, PMIX_BYTE, regtypes);
 408             if (PMIX_SUCCESS != ret) {
 409                 return ret;
 410             }
 411         }
 412     }
 413 
 414     return PMIX_SUCCESS;
 415 }
 416 
 417 pmix_status_t pmix20_bfrop_unpack_float(pmix_pointer_array_t *regtypes,
 418                                         pmix_buffer_t *buffer, void *dest,
 419                                         int32_t *num_vals, pmix_data_type_t type)
 420 {
 421     int32_t i, n;
 422     float *desttmp = (float*) dest, tmp;
 423     pmix_status_t ret;
 424     char *convert;
 425 
 426     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 427                         "pmix20_bfrop_unpack_float * %d\n", (int)*num_vals);
 428     /* check to see if there's enough data in buffer */
 429     if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(float))) {
 430         return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER;
 431     }
 432 
 433     /* unpack the data */
 434     for (i = 0; i < (*num_vals); ++i) {
 435         n=1;
 436         convert = NULL;
 437         PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &convert, &n, PMIX_STRING, regtypes);
 438         if (PMIX_SUCCESS != ret) {
 439             return ret;
 440         }
 441         if (NULL != convert) {
 442             tmp = strtof(convert, NULL);
 443             memcpy(&desttmp[i], &tmp, sizeof(tmp));
 444             free(convert);
 445         }
 446     }
 447     return PMIX_SUCCESS;
 448 }
 449 
 450 pmix_status_t pmix20_bfrop_unpack_double(pmix_pointer_array_t *regtypes,
 451                                          pmix_buffer_t *buffer, void *dest,
 452                                          int32_t *num_vals, pmix_data_type_t type)
 453 {
 454     int32_t i, n;
 455     double *desttmp = (double*) dest, tmp;
 456     pmix_status_t ret;
 457     char *convert;
 458 
 459     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 460                         "pmix20_bfrop_unpack_double * %d\n", (int)*num_vals);
 461     /* check to see if there's enough data in buffer */
 462     if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(double))) {
 463         return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER;
 464     }
 465 
 466     /* unpack the data */
 467     for (i = 0; i < (*num_vals); ++i) {
 468         n=1;
 469         convert = NULL;
 470         PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &convert, &n, PMIX_STRING, regtypes);
 471         if (PMIX_SUCCESS != ret) {
 472             return ret;
 473         }
 474         if (NULL != convert) {
 475             tmp = strtod(convert, NULL);
 476             memcpy(&desttmp[i], &tmp, sizeof(tmp));
 477             free(convert);
 478         }
 479     }
 480     return PMIX_SUCCESS;
 481 }
 482 
 483 pmix_status_t pmix20_bfrop_unpack_timeval(pmix_pointer_array_t *regtypes,
 484                                           pmix_buffer_t *buffer, void *dest,
 485                                           int32_t *num_vals, pmix_data_type_t type)
 486 {
 487     int32_t i, n;
 488     int64_t tmp[2];
 489     struct timeval *desttmp = (struct timeval *) dest, tt;
 490     pmix_status_t ret;
 491 
 492     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 493                         "pmix20_bfrop_unpack_timeval * %d\n", (int)*num_vals);
 494     /* check to see if there's enough data in buffer */
 495     if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(struct timeval))) {
 496         return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER;
 497     }
 498 
 499     /* unpack the data */
 500     for (i = 0; i < (*num_vals); ++i) {
 501         n=2;
 502         PMIX_BFROPS_UNPACK_TYPE(ret, buffer, tmp, &n, PMIX_INT64, regtypes);
 503         if (PMIX_SUCCESS != ret) {
 504             return ret;
 505         }
 506         tt.tv_sec = tmp[0];
 507         tt.tv_usec = tmp[1];
 508         memcpy(&desttmp[i], &tt, sizeof(tt));
 509     }
 510     return PMIX_SUCCESS;
 511 }
 512 
 513 pmix_status_t pmix20_bfrop_unpack_time(pmix_pointer_array_t *regtypes,
 514                                        pmix_buffer_t *buffer, void *dest,
 515                                        int32_t *num_vals, pmix_data_type_t type)
 516 {
 517     int32_t i, n;
 518     time_t *desttmp = (time_t *) dest, tmp;
 519     pmix_status_t ret;
 520     uint64_t ui64;
 521 
 522     /* time_t is a system-dependent size, so cast it
 523      * to uint64_t as a generic safe size
 524      */
 525 
 526      pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 527                          "pmix20_bfrop_unpack_time * %d\n", (int)*num_vals);
 528     /* unpack the data */
 529     for (i = 0; i < (*num_vals); ++i) {
 530         n=1;
 531         PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ui64, &n, PMIX_UINT64, regtypes);
 532         if (PMIX_SUCCESS != ret) {
 533             return ret;
 534         }
 535         tmp = (time_t)ui64;
 536         memcpy(&desttmp[i], &tmp, sizeof(tmp));
 537     }
 538     return PMIX_SUCCESS;
 539 }
 540 
 541 
 542 pmix_status_t pmix20_bfrop_unpack_status(pmix_pointer_array_t *regtypes,
 543                                          pmix_buffer_t *buffer, void *dest,
 544                                          int32_t *num_vals, pmix_data_type_t type)
 545 {
 546     pmix_status_t ret;
 547 
 548     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 549                          "pmix20_bfrop_unpack_status * %d\n", (int)*num_vals);
 550     /* check to see if there's enough data in buffer */
 551     if (pmix_bfrop_too_small(buffer, (*num_vals)*(sizeof(pmix_status_t)))) {
 552         return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER;
 553     }
 554 
 555     /* unpack the data */
 556     PMIX_BFROPS_UNPACK_TYPE(ret, buffer, dest, num_vals, PMIX_INT32, regtypes);
 557     return ret;
 558 }
 559 
 560 
 561 /* UNPACK FUNCTIONS FOR GENERIC PMIX TYPES */
 562 
 563 /*
 564  * PMIX_VALUE
 565  */
 566 static pmix_status_t unpack_val(pmix_pointer_array_t *regtypes,
 567                                 pmix_buffer_t *buffer, pmix_value_t *val)
 568 {
 569     int32_t m;
 570     pmix_status_t ret;
 571 
 572     m = 1;
 573     switch (val->type) {
 574         case PMIX_UNDEF:
 575             break;
 576         case PMIX_BOOL:
 577             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.flag, &m, PMIX_BOOL))) {
 578                 return ret;
 579             }
 580             break;
 581         case PMIX_BYTE:
 582             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.byte, &m, PMIX_BYTE))) {
 583                 return ret;
 584             }
 585             break;
 586         case PMIX_STRING:
 587             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.string, &m, PMIX_STRING))) {
 588                 return ret;
 589             }
 590             break;
 591         case PMIX_SIZE:
 592             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.size, &m, PMIX_SIZE))) {
 593                 return ret;
 594             }
 595             break;
 596         case PMIX_PID:
 597             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.pid, &m, PMIX_PID))) {
 598                 return ret;
 599             }
 600             break;
 601         case PMIX_INT:
 602             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.integer, &m, PMIX_INT))) {
 603                 return ret;
 604             }
 605             break;
 606         case PMIX_INT8:
 607             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.int8, &m, PMIX_INT8))) {
 608                 return ret;
 609             }
 610             break;
 611         case PMIX_INT16:
 612             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.int16, &m, PMIX_INT16))) {
 613                 return ret;
 614             }
 615             break;
 616         case PMIX_INT32:
 617             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.int32, &m, PMIX_INT32))) {
 618                 return ret;
 619             }
 620             break;
 621         case PMIX_INT64:
 622             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.int64, &m, PMIX_INT64))) {
 623                 return ret;
 624             }
 625             break;
 626         case PMIX_UINT:
 627             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.uint, &m, PMIX_UINT))) {
 628                 return ret;
 629             }
 630             break;
 631         case PMIX_UINT8:
 632             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.uint8, &m, PMIX_UINT8))) {
 633                 return ret;
 634             }
 635             break;
 636         case PMIX_UINT16:
 637             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.uint16, &m, PMIX_UINT16))) {
 638                 return ret;
 639             }
 640             break;
 641         case PMIX_UINT32:
 642             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.uint32, &m, PMIX_UINT32))) {
 643                 return ret;
 644             }
 645             break;
 646         case PMIX_UINT64:
 647             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.uint64, &m, PMIX_UINT64))) {
 648                 return ret;
 649             }
 650             break;
 651         case PMIX_FLOAT:
 652             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.fval, &m, PMIX_FLOAT))) {
 653                 return ret;
 654             }
 655             break;
 656         case PMIX_DOUBLE:
 657             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.dval, &m, PMIX_DOUBLE))) {
 658                 return ret;
 659             }
 660             break;
 661         case PMIX_TIMEVAL:
 662             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.tv, &m, PMIX_TIMEVAL))) {
 663                 return ret;
 664             }
 665             break;
 666         case PMIX_TIME:
 667             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.time, &m, PMIX_TIME))) {
 668                 return ret;
 669             }
 670             break;
 671         case PMIX_STATUS:
 672             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.status, &m, PMIX_STATUS))) {
 673                 return ret;
 674             }
 675             break;
 676         case PMIX_PROC:
 677             /* this field is now a pointer, so we must allocate storage for it */
 678             PMIX_PROC_CREATE(val->data.proc, m);
 679             if (NULL == val->data.proc) {
 680                 return PMIX_ERR_NOMEM;
 681             }
 682             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, val->data.proc, &m, PMIX_PROC))) {
 683                 return ret;
 684             }
 685             break;
 686         case PMIX_PROC_RANK:
 687             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.rank, &m, PMIX_PROC_RANK))) {
 688                 return ret;
 689             }
 690             break;
 691         case PMIX_BYTE_OBJECT:
 692         case PMIX_COMPRESSED_STRING:
 693             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.bo, &m, PMIX_BYTE_OBJECT))) {
 694                 return ret;
 695             }
 696             break;
 697         case PMIX_PERSIST:
 698             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.proc, &m, PMIX_PROC))) {
 699                 return ret;
 700             }
 701             break;
 702         case PMIX_POINTER:
 703             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.ptr, &m, PMIX_POINTER))) {
 704                 return ret;
 705             }
 706             break;
 707         case PMIX_SCOPE:
 708             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.scope, &m, PMIX_SCOPE))) {
 709                 return ret;
 710             }
 711             break;
 712         case PMIX_DATA_RANGE:
 713             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.range, &m, PMIX_DATA_RANGE))) {
 714                 return ret;
 715             }
 716             break;
 717         case PMIX_PROC_STATE:
 718             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.state, &m, PMIX_PROC_STATE))) {
 719                 return ret;
 720             }
 721             break;
 722         case PMIX_PROC_INFO:
 723             /* this is now a pointer, so allocate storage for it */
 724             PMIX_PROC_INFO_CREATE(val->data.pinfo, 1);
 725             if (NULL == val->data.pinfo) {
 726                 return PMIX_ERR_NOMEM;
 727             }
 728             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, val->data.pinfo, &m, PMIX_PROC_INFO))) {
 729                 return ret;
 730             }
 731             break;
 732         case PMIX_DATA_ARRAY:
 733             /* this is now a pointer, so allocate storage for it */
 734             val->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t));
 735             if (NULL == val->data.darray) {
 736                 return PMIX_ERR_NOMEM;
 737             }
 738             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, val->data.darray, &m, PMIX_DATA_ARRAY))) {
 739                 return ret;
 740             }
 741             break;
 742         case PMIX_QUERY:
 743             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, val->data.darray, &m, PMIX_QUERY))) {
 744                 return ret;
 745             }
 746             break;
 747         /**** DEPRECATED ****/
 748         case PMIX_INFO_ARRAY:
 749             /* we don't know anything about info array's so we
 750              * have to convert this to a data array */
 751             val->data.darray = (pmix_data_array_t*)calloc(1, sizeof(pmix_data_array_t));
 752             val->data.darray->type = PMIX_INFO_ARRAY;
 753             val->data.darray->size = m;
 754             /* unpack into it */
 755             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, &val->data.darray->array, &m, PMIX_INFO_ARRAY))) {
 756                 return ret;
 757             }
 758             break;
 759         /********************/
 760         default:
 761             pmix_output(0, "UNPACK-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)val->type);
 762             return PMIX_ERROR;
 763     }
 764 
 765     return PMIX_SUCCESS;
 766 }
 767 
 768 pmix_status_t pmix20_bfrop_unpack_value(pmix_pointer_array_t *regtypes,
 769                                         pmix_buffer_t *buffer, void *dest,
 770                                         int32_t *num_vals, pmix_data_type_t type)
 771 {
 772     pmix_value_t *ptr;
 773     int32_t i, n;
 774     pmix_status_t ret;
 775 
 776     ptr = (pmix_value_t *) dest;
 777     n = *num_vals;
 778 
 779     for (i = 0; i < n; ++i) {
 780         /* unpack the type */
 781         if (PMIX_SUCCESS != (ret = pmix20_bfrop_get_data_type(regtypes, buffer, &ptr[i].type))) {
 782             return ret;
 783         }
 784         /* unpack value */
 785         if (PMIX_SUCCESS != (ret = unpack_val(regtypes, buffer, &ptr[i])) ) {
 786             return ret;
 787         }
 788     }
 789     return PMIX_SUCCESS;
 790 }
 791 
 792 pmix_status_t pmix20_bfrop_unpack_info(pmix_pointer_array_t *regtypes,
 793                                        pmix_buffer_t *buffer, void *dest,
 794                                        int32_t *num_vals, pmix_data_type_t type)
 795 {
 796     pmix_info_t *ptr;
 797     int32_t i, n, m;
 798     pmix_status_t ret;
 799     char *tmp;
 800 
 801     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 802                         "pmix20_bfrop_unpack: %d info", *num_vals);
 803 
 804     ptr = (pmix_info_t *) dest;
 805     n = *num_vals;
 806 
 807     for (i = 0; i < n; ++i) {
 808         memset(ptr[i].key, 0, sizeof(ptr[i].key));
 809         memset(&ptr[i].value, 0, sizeof(pmix_value_t));
 810         /* unpack key */
 811         m=1;
 812         tmp = NULL;
 813         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_string(regtypes, buffer, &tmp, &m, PMIX_STRING))) {
 814             PMIX_ERROR_LOG(ret);
 815             return ret;
 816         }
 817         if (NULL == tmp) {
 818             PMIX_ERROR_LOG(PMIX_ERROR);
 819             return PMIX_ERROR;
 820         }
 821         pmix_strncpy(ptr[i].key, tmp, PMIX_MAX_KEYLEN);
 822         free(tmp);
 823         /* unpack the flags */
 824         m=1;
 825         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_infodirs(regtypes, buffer, &ptr[i].flags, &m, PMIX_INFO_DIRECTIVES))) {
 826             PMIX_ERROR_LOG(ret);
 827             return ret;
 828         }
 829         /* unpack value - since the value structure is statically-defined
 830          * instead of a pointer in this struct, we directly unpack it to
 831          * avoid the malloc */
 832          m=1;
 833          if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_int(regtypes, buffer, &ptr[i].value.type, &m, PMIX_INT))) {
 834             PMIX_ERROR_LOG(ret);
 835             return ret;
 836         }
 837         pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 838                             "pmix20_bfrop_unpack: info type %d", ptr[i].value.type);
 839         m=1;
 840         if (PMIX_SUCCESS != (ret = unpack_val(regtypes, buffer, &ptr[i].value))) {
 841             PMIX_ERROR_LOG(ret);
 842             return ret;
 843         }
 844     }
 845     return PMIX_SUCCESS;
 846 }
 847 
 848 pmix_status_t pmix20_bfrop_unpack_pdata(pmix_pointer_array_t *regtypes,
 849                                         pmix_buffer_t *buffer, void *dest,
 850                                         int32_t *num_vals, pmix_data_type_t type)
 851 {
 852     pmix_pdata_t *ptr;
 853     int32_t i, n, m;
 854     pmix_status_t ret;
 855     char *tmp;
 856 
 857     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 858                         "pmix20_bfrop_unpack: %d pdata", *num_vals);
 859 
 860     ptr = (pmix_pdata_t *) dest;
 861     n = *num_vals;
 862 
 863     for (i = 0; i < n; ++i) {
 864         PMIX_PDATA_CONSTRUCT(&ptr[i]);
 865         /* unpack the proc */
 866         m=1;
 867         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_proc(regtypes, buffer, &ptr[i].proc, &m, PMIX_PROC))) {
 868             return ret;
 869         }
 870         /* unpack key */
 871         m=1;
 872         tmp = NULL;
 873         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_string(regtypes, buffer, &tmp, &m, PMIX_STRING))) {
 874             return ret;
 875         }
 876         if (NULL == tmp) {
 877             return PMIX_ERROR;
 878         }
 879         pmix_strncpy(ptr[i].key, tmp, PMIX_MAX_KEYLEN);
 880         free(tmp);
 881         /* unpack value - since the value structure is statically-defined
 882          * instead of a pointer in this struct, we directly unpack it to
 883          * avoid the malloc */
 884          m=1;
 885          if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_int(regtypes, buffer, &ptr[i].value.type, &m, PMIX_INT))) {
 886             return ret;
 887         }
 888         pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 889                             "pmix20_bfrop_unpack: pdata type %d", ptr[i].value.type);
 890         m=1;
 891         if (PMIX_SUCCESS != (ret = unpack_val(regtypes, buffer, &ptr[i].value))) {
 892             return ret;
 893         }
 894     }
 895     return PMIX_SUCCESS;
 896 }
 897 
 898 pmix_status_t pmix20_bfrop_unpack_buf(pmix_pointer_array_t *regtypes,
 899                                       pmix_buffer_t *buffer, void *dest,
 900                                       int32_t *num_vals, pmix_data_type_t type)
 901 {
 902     pmix_buffer_t *ptr;
 903     int32_t i, n, m;
 904     pmix_status_t ret;
 905     size_t nbytes;
 906 
 907     ptr = (pmix_buffer_t *) dest;
 908     n = *num_vals;
 909 
 910     for (i = 0; i < n; ++i) {
 911         /* unpack the number of bytes */
 912         m=1;
 913         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_sizet(regtypes, buffer, &nbytes, &m, PMIX_SIZE))) {
 914             return ret;
 915         }
 916         m = nbytes;
 917         /* setup the buffer's data region */
 918         if (0 < nbytes) {
 919             ptr[i].base_ptr = (char*)malloc(nbytes);
 920             /* unpack the bytes */
 921             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_byte(regtypes, buffer, ptr[i].base_ptr, &m, PMIX_BYTE))) {
 922                 return ret;
 923             }
 924         }
 925         ptr[i].pack_ptr = ptr[i].base_ptr + m;
 926         ptr[i].unpack_ptr = ptr[i].base_ptr;
 927         ptr[i].bytes_allocated = nbytes;
 928         ptr[i].bytes_used = m;
 929     }
 930     return PMIX_SUCCESS;
 931 }
 932 
 933 pmix_status_t pmix20_bfrop_unpack_proc(pmix_pointer_array_t *regtypes,
 934                                        pmix_buffer_t *buffer, void *dest,
 935                                        int32_t *num_vals, pmix_data_type_t type)
 936 {
 937     pmix_proc_t *ptr;
 938     int32_t i, n, m;
 939     pmix_status_t ret;
 940     char *tmp;
 941 
 942     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 943                         "pmix20_bfrop_unpack: %d procs", *num_vals);
 944 
 945     ptr = (pmix_proc_t *) dest;
 946     n = *num_vals;
 947 
 948     for (i = 0; i < n; ++i) {
 949         pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 950                             "pmix20_bfrop_unpack: init proc[%d]", i);
 951         memset(&ptr[i], 0, sizeof(pmix_proc_t));
 952         /* unpack nspace */
 953         m=1;
 954         tmp = NULL;
 955         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_string(regtypes, buffer, &tmp, &m, PMIX_STRING))) {
 956             return ret;
 957         }
 958         if (NULL == tmp) {
 959             return PMIX_ERROR;
 960         }
 961         pmix_strncpy(ptr[i].nspace, tmp, PMIX_MAX_NSLEN);
 962         free(tmp);
 963         /* unpack the rank */
 964         m=1;
 965         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_rank(regtypes, buffer, &ptr[i].rank, &m, PMIX_PROC_RANK))) {
 966             return ret;
 967         }
 968     }
 969     return PMIX_SUCCESS;
 970 }
 971 
 972 pmix_status_t pmix20_bfrop_unpack_app(pmix_pointer_array_t *regtypes,
 973                                       pmix_buffer_t *buffer, void *dest,
 974                                       int32_t *num_vals, pmix_data_type_t type)
 975 {
 976     pmix_app_t *ptr;
 977     int32_t i, k, n, m;
 978     pmix_status_t ret;
 979     int32_t nval;
 980     char *tmp;
 981 
 982     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
 983                         "pmix20_bfrop_unpack: %d apps", *num_vals);
 984 
 985     ptr = (pmix_app_t *) dest;
 986     n = *num_vals;
 987 
 988     for (i = 0; i < n; ++i) {
 989         /* initialize the fields */
 990         PMIX_APP_CONSTRUCT(&ptr[i]);
 991         /* unpack cmd */
 992         m=1;
 993         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_string(regtypes, buffer, &ptr[i].cmd, &m, PMIX_STRING))) {
 994             return ret;
 995         }
 996         /* unpack argc */
 997         m=1;
 998         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_int(regtypes, buffer, &nval, &m, PMIX_INT32))) {
 999             return ret;
1000         }
1001         /* unpack argv */
1002         for (k=0; k < nval; k++) {
1003             m=1;
1004             tmp = NULL;
1005             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_string(regtypes, buffer, &tmp, &m, PMIX_STRING))) {
1006                 return ret;
1007             }
1008             if (NULL == tmp) {
1009                 return PMIX_ERROR;
1010             }
1011             pmix_argv_append_nosize(&ptr[i].argv, tmp);
1012             free(tmp);
1013         }
1014         /* unpack env */
1015         m=1;
1016         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_int32(regtypes, buffer, &nval, &m, PMIX_INT32))) {
1017             return ret;
1018         }
1019         for (k=0; k < nval; k++) {
1020             m=1;
1021             tmp = NULL;
1022             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_string(regtypes, buffer, &tmp, &m, PMIX_STRING))) {
1023                 return ret;
1024             }
1025             if (NULL == tmp) {
1026                 return PMIX_ERROR;
1027             }
1028             pmix_argv_append_nosize(&ptr[i].env, tmp);
1029             free(tmp);
1030         }
1031         /* unpack cwd */
1032         m=1;
1033         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_string(regtypes, buffer, &ptr[i].cwd, &m, PMIX_STRING))) {
1034             return ret;
1035         }
1036         /* unpack maxprocs */
1037         m=1;
1038         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_int(regtypes, buffer, &ptr[i].maxprocs, &m, PMIX_INT))) {
1039             return ret;
1040         }
1041         /* unpack info array */
1042         m=1;
1043         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_sizet(regtypes, buffer, &ptr[i].ninfo, &m, PMIX_SIZE))) {
1044             return ret;
1045         }
1046         if (0 < ptr[i].ninfo) {
1047             PMIX_INFO_CREATE(ptr[i].info, ptr[i].ninfo);
1048             m = ptr[i].ninfo;
1049             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_info(regtypes, buffer, ptr[i].info, &m, PMIX_INFO))) {
1050                 return ret;
1051             }
1052         }
1053     }
1054     return PMIX_SUCCESS;
1055 }
1056 
1057 pmix_status_t pmix20_bfrop_unpack_kval(pmix_pointer_array_t *regtypes,
1058                                        pmix_buffer_t *buffer, void *dest,
1059                                        int32_t *num_vals, pmix_data_type_t type)
1060 {
1061     pmix_kval_t *ptr;
1062     int32_t i, n, m;
1063     pmix_status_t ret;
1064 
1065     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
1066                         "pmix20_bfrop_unpack: %d kvals", *num_vals);
1067 
1068     ptr = (pmix_kval_t*) dest;
1069     n = *num_vals;
1070 
1071     for (i = 0; i < n; ++i) {
1072         PMIX_CONSTRUCT(&ptr[i], pmix_kval_t);
1073         /* unpack the key */
1074         m = 1;
1075         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_string(regtypes, buffer, &ptr[i].key, &m, PMIX_STRING))) {
1076             PMIX_ERROR_LOG(ret);
1077             return ret;
1078         }
1079         /* allocate the space */
1080         ptr[i].value = (pmix_value_t*)malloc(sizeof(pmix_value_t));
1081         /* unpack the value */
1082         m = 1;
1083         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_value(regtypes, buffer, ptr[i].value, &m, PMIX_VALUE))) {
1084             PMIX_ERROR_LOG(ret);
1085             return ret;
1086         }
1087     }
1088     return PMIX_SUCCESS;
1089 }
1090 
1091 pmix_status_t pmix20_bfrop_unpack_modex(pmix_pointer_array_t *regtypes,
1092                                         pmix_buffer_t *buffer, void *dest,
1093                                         int32_t *num_vals, pmix_data_type_t type)
1094 {
1095     pmix_modex_data_t *ptr;
1096     int32_t i, n, m;
1097     pmix_status_t ret;
1098 
1099     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
1100                         "pmix20_bfrop_unpack: %d modex", *num_vals);
1101 
1102     ptr = (pmix_modex_data_t *) dest;
1103     n = *num_vals;
1104 
1105     for (i = 0; i < n; ++i) {
1106         memset(&ptr[i], 0, sizeof(pmix_modex_data_t));
1107         /* unpack the number of bytes */
1108         m=1;
1109         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_sizet(regtypes, buffer, &ptr[i].size, &m, PMIX_SIZE))) {
1110             return ret;
1111         }
1112         if (0 < ptr[i].size) {
1113             ptr[i].blob = (uint8_t*)malloc(ptr[i].size * sizeof(uint8_t));
1114             m=ptr[i].size;
1115             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_byte(regtypes, buffer, ptr[i].blob, &m, PMIX_UINT8))) {
1116                 return ret;
1117             }
1118         }
1119     }
1120     return PMIX_SUCCESS;
1121 }
1122 
1123 pmix_status_t pmix20_bfrop_unpack_persist(pmix_pointer_array_t *regtypes,
1124                                           pmix_buffer_t *buffer, void *dest,
1125                                           int32_t *num_vals, pmix_data_type_t type)
1126 {
1127     return pmix20_bfrop_unpack_byte(regtypes, buffer, dest, num_vals, PMIX_UINT8);
1128 }
1129 
1130 pmix_status_t pmix20_bfrop_unpack_scope(pmix_pointer_array_t *regtypes,
1131                                         pmix_buffer_t *buffer, void *dest,
1132                                         int32_t *num_vals, pmix_data_type_t type)
1133 {
1134     return pmix20_bfrop_unpack_byte(regtypes, buffer, dest, num_vals, PMIX_UINT8);
1135 }
1136 
1137 pmix_status_t pmix20_bfrop_unpack_range(pmix_pointer_array_t *regtypes,
1138                                         pmix_buffer_t *buffer, void *dest,
1139                                         int32_t *num_vals, pmix_data_type_t type)
1140 {
1141     return pmix20_bfrop_unpack_byte(regtypes, buffer, dest, num_vals, PMIX_UINT8);
1142 }
1143 
1144 pmix_status_t pmix20_bfrop_unpack_cmd(pmix_pointer_array_t *regtypes,
1145                                       pmix_buffer_t *buffer, void *dest,
1146                                       int32_t *num_vals, pmix_data_type_t type)
1147 {
1148     return pmix20_bfrop_unpack_byte(regtypes, buffer, dest, num_vals, PMIX_UINT8);
1149 }
1150 
1151 pmix_status_t pmix20_bfrop_unpack_infodirs(pmix_pointer_array_t *regtypes,
1152                                            pmix_buffer_t *buffer, void *dest,
1153                                            int32_t *num_vals, pmix_data_type_t type)
1154 {
1155     return pmix20_bfrop_unpack_int32(regtypes, buffer, dest, num_vals, PMIX_UINT32);
1156 }
1157 
1158 pmix_status_t pmix20_bfrop_unpack_bo(pmix_pointer_array_t *regtypes,
1159                                      pmix_buffer_t *buffer, void *dest,
1160                                      int32_t *num_vals, pmix_data_type_t type)
1161 {
1162     pmix_byte_object_t *ptr;
1163     int32_t i, n, m;
1164     pmix_status_t ret;
1165 
1166     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
1167                         "pmix20_bfrop_unpack: %d byte_object", *num_vals);
1168 
1169     ptr = (pmix_byte_object_t *) dest;
1170     n = *num_vals;
1171 
1172     for (i = 0; i < n; ++i) {
1173         memset(&ptr[i], 0, sizeof(pmix_byte_object_t));
1174         /* unpack the number of bytes */
1175         m=1;
1176         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_sizet(regtypes, buffer, &ptr[i].size, &m, PMIX_SIZE))) {
1177             return ret;
1178         }
1179         if (0 < ptr[i].size) {
1180             ptr[i].bytes = (char*)malloc(ptr[i].size * sizeof(char));
1181             m=ptr[i].size;
1182             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_byte(regtypes, buffer, ptr[i].bytes, &m, PMIX_BYTE))) {
1183                 return ret;
1184             }
1185         }
1186     }
1187     return PMIX_SUCCESS;
1188 }
1189 
1190 pmix_status_t pmix20_bfrop_unpack_ptr(pmix_pointer_array_t *regtypes,
1191                                       pmix_buffer_t *buffer, void *dest,
1192                                       int32_t *num_vals, pmix_data_type_t type)
1193 {
1194     uint8_t foo=1;
1195     int32_t cnt=1;
1196 
1197     /* it obviously makes no sense to pack a pointer and
1198      * send it somewhere else, so we just unpack the sentinel */
1199     return pmix20_bfrop_unpack_byte(regtypes, buffer, &foo, &cnt, PMIX_UINT8);
1200 }
1201 
1202 pmix_status_t pmix20_bfrop_unpack_pstate(pmix_pointer_array_t *regtypes,
1203                                          pmix_buffer_t *buffer, void *dest,
1204                                          int32_t *num_vals, pmix_data_type_t type)
1205 {
1206     return pmix20_bfrop_unpack_byte(regtypes, buffer, dest, num_vals, PMIX_UINT8);
1207 }
1208 
1209 
1210 pmix_status_t pmix20_bfrop_unpack_pinfo(pmix_pointer_array_t *regtypes,
1211                                         pmix_buffer_t *buffer, void *dest,
1212                                         int32_t *num_vals, pmix_data_type_t type)
1213 {
1214     pmix_proc_info_t *ptr;
1215     int32_t i, n, m;
1216     pmix_status_t ret;
1217 
1218     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
1219                         "pmix20_bfrop_unpack: %d pinfo", *num_vals);
1220 
1221     ptr = (pmix_proc_info_t *) dest;
1222     n = *num_vals;
1223 
1224     for (i = 0; i < n; ++i) {
1225         PMIX_PROC_INFO_CONSTRUCT(&ptr[i]);
1226         /* unpack the proc */
1227         m=1;
1228         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_proc(regtypes, buffer, &ptr[i].proc, &m, PMIX_PROC))) {
1229             return ret;
1230         }
1231         /* unpack the hostname */
1232         m=1;
1233         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_string(regtypes, buffer, &ptr[i].hostname, &m, PMIX_STRING))) {
1234             return ret;
1235         }
1236         /* unpack the executable */
1237         m=1;
1238         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_string(regtypes, buffer, &ptr[i].executable_name, &m, PMIX_STRING))) {
1239             return ret;
1240         }
1241         /* unpack pid */
1242          m=1;
1243          if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_pid(regtypes, buffer, &ptr[i].pid, &m, PMIX_PID))) {
1244             return ret;
1245         }
1246         /* unpack state */
1247          m=1;
1248          if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_pstate(regtypes, buffer, &ptr[i].state, &m, PMIX_PROC_STATE))) {
1249             return ret;
1250         }
1251     }
1252     return PMIX_SUCCESS;
1253 }
1254 
1255 pmix_status_t pmix20_bfrop_unpack_darray(pmix_pointer_array_t *regtypes,
1256                                          pmix_buffer_t *buffer, void *dest,
1257                                          int32_t *num_vals, pmix_data_type_t type)
1258 {
1259     pmix_data_array_t *ptr;
1260     int32_t i, n, m;
1261     pmix_status_t ret;
1262     size_t nbytes;
1263 
1264     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
1265                         "pmix20_bfrop_unpack: %d data arrays", *num_vals);
1266 
1267     ptr = (pmix_data_array_t *) dest;
1268     n = *num_vals;
1269 
1270     for (i = 0; i < n; ++i) {
1271         memset(&ptr[i], 0, sizeof(pmix_data_array_t));
1272         /* unpack the type */
1273         m=1;
1274         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_datatype(regtypes, buffer, &ptr[i].type, &m, PMIX_DATA_TYPE))) {
1275             return ret;
1276         }
1277         /* unpack the number of array elements */
1278         m=1;
1279         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_sizet(regtypes, buffer, &ptr[i].size, &m, PMIX_SIZE))) {
1280             return ret;
1281         }
1282         if (0 == ptr[i].size || PMIX_UNDEF == ptr[i].type) {
1283             /* nothing else to do */
1284             continue;
1285         }
1286         /* allocate storage for the array and unpack the array elements */
1287         m = ptr[i].size;
1288         switch(ptr[i].type) {
1289             case PMIX_BOOL:
1290                 nbytes = sizeof(bool);
1291                 break;
1292             case PMIX_BYTE:
1293             case PMIX_INT8:
1294             case PMIX_UINT8:
1295                 nbytes = sizeof(int8_t);
1296                 break;
1297             case PMIX_INT16:
1298             case PMIX_UINT16:
1299                 nbytes = sizeof(int16_t);
1300                 break;
1301             case PMIX_INT32:
1302             case PMIX_UINT32:
1303                 nbytes = sizeof(int32_t);
1304                 break;
1305             case PMIX_INT64:
1306             case PMIX_UINT64:
1307                 nbytes = sizeof(int64_t);
1308                 break;
1309             case PMIX_STRING:
1310                 nbytes = sizeof(char*);
1311                 break;
1312             case PMIX_SIZE:
1313                 nbytes = sizeof(size_t);
1314                 break;
1315             case PMIX_PID:
1316                 nbytes = sizeof(pid_t);
1317                 break;
1318             case PMIX_INT:
1319             case PMIX_UINT:
1320                 nbytes = sizeof(int);
1321                 break;
1322             case PMIX_FLOAT:
1323                 nbytes = sizeof(float);
1324                 break;
1325             case PMIX_DOUBLE:
1326                 nbytes = sizeof(double);
1327                 break;
1328             case PMIX_TIMEVAL:
1329                 nbytes = sizeof(struct timeval);
1330                 break;
1331             case PMIX_TIME:
1332                 nbytes = sizeof(time_t);
1333                 break;
1334             case PMIX_STATUS:
1335                 nbytes = sizeof(pmix_status_t);
1336                 break;
1337             case PMIX_INFO:
1338                 nbytes = sizeof(pmix_info_t);
1339                 break;
1340             case PMIX_PROC:
1341                 nbytes = sizeof(pmix_proc_t);
1342                 break;
1343             case PMIX_BYTE_OBJECT:
1344             case PMIX_COMPRESSED_STRING:
1345                 nbytes = sizeof(pmix_byte_object_t);
1346                 break;
1347             case PMIX_PERSIST:
1348                 nbytes = sizeof(pmix_persistence_t);
1349                 break;
1350             case PMIX_SCOPE:
1351                 nbytes = sizeof(pmix_scope_t);
1352                 break;
1353             case PMIX_DATA_RANGE:
1354                 nbytes = sizeof(pmix_data_range_t);
1355                 break;
1356             case PMIX_PROC_STATE:
1357                 nbytes = sizeof(pmix_proc_state_t);
1358                 break;
1359             case PMIX_PROC_INFO:
1360                 nbytes = sizeof(pmix_proc_info_t);
1361                 break;
1362             case PMIX_QUERY:
1363                 nbytes = sizeof(pmix_query_t);
1364             default:
1365                 return PMIX_ERR_NOT_SUPPORTED;
1366         }
1367         if (NULL == (ptr[i].array = malloc(m * nbytes))) {
1368             return PMIX_ERR_NOMEM;
1369         }
1370         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_buffer(regtypes, buffer, ptr[i].array, &m, ptr[i].type))) {
1371             return ret;
1372         }
1373     }
1374     return PMIX_SUCCESS;
1375 }
1376 
1377 pmix_status_t pmix20_bfrop_unpack_rank(pmix_pointer_array_t *regtypes,
1378                                        pmix_buffer_t *buffer, void *dest,
1379                                        int32_t *num_vals, pmix_data_type_t type)
1380 {
1381     return pmix20_bfrop_unpack_int32(regtypes, buffer, dest, num_vals, PMIX_UINT32);
1382 }
1383 
1384 pmix_status_t pmix20_bfrop_unpack_query(pmix_pointer_array_t *regtypes,
1385                                         pmix_buffer_t *buffer, void *dest,
1386                                         int32_t *num_vals, pmix_data_type_t type)
1387 {
1388     pmix_query_t *ptr;
1389     int32_t i, n, m;
1390     pmix_status_t ret;
1391     int32_t nkeys;
1392 
1393     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
1394                         "pmix20_bfrop_unpack: %d queries", *num_vals);
1395 
1396     ptr = (pmix_query_t *) dest;
1397     n = *num_vals;
1398 
1399     for (i = 0; i < n; ++i) {
1400         PMIX_QUERY_CONSTRUCT(&ptr[i]);
1401         /* unpack the number of keys */
1402         m=1;
1403         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_int32(regtypes, buffer, &nkeys, &m, PMIX_INT32))) {
1404             return ret;
1405         }
1406         if (0 < nkeys) {
1407             /* unpack the keys */
1408             if (NULL == (ptr[i].keys = (char**)calloc(nkeys+1, sizeof(char*)))) {
1409                 return PMIX_ERR_NOMEM;
1410             }
1411             /* unpack keys */
1412             m=nkeys;
1413             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_string(regtypes, buffer, ptr[i].keys, &m, PMIX_STRING))) {
1414                 return ret;
1415             }
1416         }
1417         /* unpack the number of qualifiers */
1418         m=1;
1419         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_sizet(regtypes, buffer, &ptr[i].nqual, &m, PMIX_SIZE))) {
1420             return ret;
1421         }
1422         if (0 < ptr[i].nqual) {
1423             /* unpack the qualifiers */
1424             PMIX_INFO_CREATE(ptr[i].qualifiers, ptr[i].nqual);
1425             m =  ptr[i].nqual;
1426             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_info(regtypes, buffer, ptr[i].qualifiers, &m, PMIX_INFO))) {
1427                 return ret;
1428             }
1429         }
1430     }
1431     return PMIX_SUCCESS;
1432 }
1433 
1434 pmix_status_t pmix20_bfrop_unpack_alloc_directive(pmix_pointer_array_t *regtypes,
1435                                                   pmix_buffer_t *buffer, void *dest,
1436                                                   int32_t *num_vals, pmix_data_type_t type)
1437 {
1438     return pmix20_bfrop_unpack_byte(regtypes, buffer, dest, num_vals, PMIX_UINT8);
1439 }
1440 
1441 
1442 /**** DEPRECATED ****/
1443 pmix_status_t pmix20_bfrop_unpack_array(pmix_pointer_array_t *regtypes,
1444                                         pmix_buffer_t *buffer, void *dest,
1445                                         int32_t *num_vals, pmix_data_type_t type)
1446 {
1447     pmix_info_array_t *ptr;
1448     int32_t i, n, m;
1449     pmix_status_t ret;
1450 
1451     pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
1452                         "pmix20_bfrop_unpack: %d info arrays", *num_vals);
1453 
1454     ptr = (pmix_info_array_t*) dest;
1455     n = *num_vals;
1456 
1457     for (i = 0; i < n; ++i) {
1458         pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output,
1459                             "pmix20_bfrop_unpack: init array[%d]", i);
1460         memset(&ptr[i], 0, sizeof(pmix_info_array_t));
1461         /* unpack the size of this array */
1462         m=1;
1463         if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_sizet(regtypes, buffer, &ptr[i].size, &m, PMIX_SIZE))) {
1464             return ret;
1465         }
1466         if (0 < ptr[i].size) {
1467             ptr[i].array = (pmix_info_t*)malloc(ptr[i].size * sizeof(pmix_info_t));
1468             m=ptr[i].size;
1469             if (PMIX_SUCCESS != (ret = pmix20_bfrop_unpack_value(regtypes, buffer, ptr[i].array, &m, PMIX_INFO))) {
1470                 return ret;
1471             }
1472         }
1473     }
1474     return PMIX_SUCCESS;
1475 }
1476 /********************/

/* [<][>][^][v][top][bottom][index][help] */