root/opal/mca/pmix/pmix4x/pmix/contrib/perf_tools/pmi2_utils.c

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

DEFINITIONS

This source file includes following definitions.
  1. pmi_base64_encsym
  2. pmi_base64_decsym
  3. pmi_base64_encode_block
  4. pmi_base64_decode_block
  5. pmi_encode
  6. pmi_decode

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2012-2015 Los Alamos National Security, LLC.  All rights
   4  *                         reserved.
   5  * Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
   6  * Copyright (c) 2014-2016 Research Organization for Information Science
   7  *                         and Technology (RIST). All rights reserved.
   8  * Copyright (c) 2016      Mellanox Technologies, Inc.
   9  *                         All rights reserved.
  10  * $COPYRIGHT$
  11  *
  12  * Additional copyrights may follow
  13  *
  14  * $HEADER$
  15  *
  16  */
  17 
  18 /* This code was taken from Open MPI project, file
  19    opal/mca/pmix/base/pmix_base_fns.c
  20 */
  21 
  22 #include <assert.h>
  23 #include <string.h>
  24 #include "pmi2_utils.h"
  25 
  26 /* base64 encoding with illegal (to Cray PMI) characters removed ('=' is replaced by ' ') */
  27 static inline unsigned char pmi_base64_encsym (unsigned char value) {
  28     assert (value < 64);
  29 
  30     if (value < 26) {
  31     return 'A' + value;
  32     } else if (value < 52) {
  33     return 'a' + (value - 26);
  34     } else if (value < 62) {
  35     return '0' + (value - 52);
  36     }
  37 
  38     return (62 == value) ? '+' : '/';
  39 }
  40 
  41 static inline unsigned char pmi_base64_decsym (unsigned char value) {
  42     if ('+' == value) {
  43     return 62;
  44     } else if ('/' == value) {
  45     return 63;
  46     } else if (' ' == value) {
  47     return 64;
  48     } else if (value <= '9') {
  49     return (value - '0') + 52;
  50     } else if (value <= 'Z') {
  51     return (value - 'A');
  52     } else if (value <= 'z') {
  53     return (value - 'a') + 26;
  54     }
  55 
  56     return 64;
  57 }
  58 
  59 static inline void pmi_base64_encode_block (const unsigned char in[3], char out[4], int len) {
  60     out[0] = pmi_base64_encsym (in[0] >> 2);
  61     out[1] = pmi_base64_encsym (((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4));
  62     /* Cray PMI doesn't allow = in PMI attributes so pad with spaces */
  63     out[2] = 1 < len ? pmi_base64_encsym(((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)) : ' ';
  64     out[3] = 2 < len ? pmi_base64_encsym(in[2] & 0x3f) : ' ';
  65 }
  66 
  67 static inline int pmi_base64_decode_block (const char in[4], unsigned char out[3]) {
  68     char in_dec[4];
  69 
  70     in_dec[0] = pmi_base64_decsym (in[0]);
  71     in_dec[1] = pmi_base64_decsym (in[1]);
  72     in_dec[2] = pmi_base64_decsym (in[2]);
  73     in_dec[3] = pmi_base64_decsym (in[3]);
  74 
  75     out[0] = in_dec[0] << 2 | in_dec[1] >> 4;
  76     if (64 == in_dec[2]) {
  77     return 1;
  78     }
  79 
  80     out[1] = in_dec[1] << 4 | in_dec[2] >> 2;
  81     if (64 == in_dec[3]) {
  82     return 2;
  83     }
  84 
  85     out[2] = ((in_dec[2] << 6) & 0xc0) | in_dec[3];
  86     return 3;
  87 }
  88 
  89 
  90 /* PMI only supports strings. For now, do a simple base64. */
  91 char *pmi_encode(const void *val, size_t vallen)
  92 {
  93     char *outdata, *tmp;
  94     size_t i;
  95 
  96     outdata = calloc (((2 + vallen) * 4) / 3 + 2, 1);
  97     if (NULL == outdata) {
  98     return NULL;
  99     }
 100 
 101     for (i = 0, tmp = outdata ; i < vallen ; i += 3, tmp += 4) {
 102         pmi_base64_encode_block((unsigned char *) val + i, tmp, vallen - i);
 103     }
 104 
 105     tmp[0] = (unsigned char)'\0';
 106 
 107     return outdata;
 108 }
 109 
 110 uint8_t *pmi_decode (const char *data, size_t *retlen)
 111 {
 112     size_t input_len = strlen(data) / 4;
 113     unsigned char *ret;
 114     int out_len;
 115     size_t i;
 116 
 117     /* default */
 118     *retlen = 0;
 119 
 120     ret = calloc (1, 3 * input_len + 1);
 121     if (NULL == ret) {
 122         return ret;
 123     }
 124 
 125     for (i = 0, out_len = 0 ; i < input_len ; i++, data += 4) {
 126     out_len += pmi_base64_decode_block(data, ret + 3 * i);
 127     }
 128 
 129     ret[out_len] = '\0';
 130     *retlen = out_len;
 131     return ret;
 132 }

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