Esempio n. 1
0
File: text.c Progetto: mytestbed/oml
int
text_read_msg_start (struct oml_message *msg, MBuffer *mbuf)
{
  int len = mbuf_find (mbuf, '\n'); // Find length of line
  OmlValue value;
  int bytes = 0;

  oml_value_init(&value);

  if (len == -1)
    return 0; // Haven't got a full line

  msg->length = (uint32_t)len + 1;

  /* Read the timestamp first */
  oml_value_set_type(&value, OML_DOUBLE_VALUE);
  bytes = text_read_value (mbuf, &value, len);
  if (bytes == -1)
    return -1;
  else
    len -= bytes;

  msg->timestamp = omlc_get_double(*oml_value_get_value(&value));

  /* Read the stream index */
  oml_value_set_type(&value, OML_UINT32_VALUE);
  bytes = text_read_value (mbuf, &value, len);
  if (bytes == -1)
    return -1;
  else
    len -= bytes;

  msg->stream = omlc_get_uint32(*oml_value_get_value(&value));

  /* Read the sequence number */
  oml_value_set_type(&value, OML_UINT32_VALUE);
  bytes = text_read_value (mbuf, &value, len);
  if (bytes == -1)
    return -1;
  else
    len -= bytes;

  msg->seqno = omlc_get_uint32(*oml_value_get_value(&value));

  oml_value_reset(&value);

  return msg->length;
}
Esempio n. 2
0
static int
output (
  OmlFilter* f,
  OmlWriter* writer
) {
  InstanceData* self = (InstanceData*)f->instance_data;

  if (self->sample_count <= 0)
    return 1;

  omlc_set_double(*oml_value_get_value(&self->result[1]), 1.0 * self->s / (self->sample_count - 1));
  omlc_set_double(*oml_value_get_value(&self->result[0]), sqrt (omlc_get_double(*oml_value_get_value(&self->result[1]))));

  self->m = 0;
  self->s = 0;
  self->sample_count = 0;

  writer->out (writer, self->result, f->output_count);
  return 0;
}
Esempio n. 3
0
/** Cast the data contained in an OmlValue to an int.
 *
 * \param value pointer to OmlValue containing the data to cast
 * \return an integer, which defaults to 0 on error
 */
int
oml_value_to_int (OmlValue *value)
{
    OmlValueU *v = oml_value_get_value(value);
    OmlValueT type = oml_value_get_type(value);
    switch (type) {
    case OML_LONG_VALUE:
        logwarn("%s(): OML_LONG_VALUE is deprecated, please use OML_INT32_VALUE instead\n", __FUNCTION__);
        return (int) omlc_get_long(*v);
    case OML_INT32_VALUE:
        return (int) omlc_get_int32(*v);
    case OML_UINT32_VALUE:
        return (int) omlc_get_uint32(*v);
    case OML_INT64_VALUE:
        return (int) omlc_get_int64(*v);
    case OML_UINT64_VALUE:
        return (int) omlc_get_uint64(*v);
    case OML_DOUBLE_VALUE:
        return (int) omlc_get_double(*v);
    default:
        logerror("%s() for type '%d' not implemented'\n", __FUNCTION__, type);
        return 0;
    }
}
Esempio n. 4
0
/** Convert data stored in an OmlValueU of the given OmlValueT to a string representation.
 *
 * The given buffer will contain a nul-terminated C string.
 *
 * \param value pointer to OmlValue containing data
 * \param buf buffer to put the textual representation of the value in
 * \param size size of the buffer
 * \return a pointer to buf, or NULL on error
 */
static char*
oml_value_ut_to_s(OmlValueU* value, OmlValueT type, char *buf, size_t size)
{
    size_t i, m, n = 0;

    switch (type) {
    case OML_LONG_VALUE:
        logwarn("%s(): OML_LONG_VALUE is deprecated, please use OML_INT32_VALUE instead\n", __FUNCTION__);
        n += snprintf(buf, size, "%ld", omlc_get_long(*value));
        break;
    case OML_INT32_VALUE:
        n += snprintf(buf, size, "%" PRId32, omlc_get_int32(*value));
        break;
    case OML_UINT32_VALUE:
        n += snprintf(buf, size, "%" PRIu32, omlc_get_uint32(*value));
        break;
    case OML_INT64_VALUE:
        n += snprintf(buf, size, "%" PRId64, omlc_get_int64(*value));
        break;
    case OML_UINT64_VALUE:
        n += snprintf(buf, size, "%" PRIu64, omlc_get_uint64(*value));
        break;
    case OML_DOUBLE_VALUE:
        n += snprintf(buf, size, "%f", omlc_get_double(*value));
        break;
    case OML_STRING_VALUE:
        n += snprintf(buf, size, "%s", omlc_get_string_ptr(*value));
        break;
    case OML_DATETIME_VALUE:
        n += snprintf(buf, size, "%s", omlc_get_string_ptr(*value));
        break;
    case OML_BLOB_VALUE:
        strncpy(buf, "0x", size);
        for(n = 2, i = 0; i < omlc_get_blob_length(*value) &&  n < size; i++) /* n = 2 because of the 0x prefix */
            n += snprintf(buf + n, size - n, "%02x", ((uint8_t*)(omlc_get_blob_ptr(*value)))[i]);
        break;
    case OML_GUID_VALUE:
        n += omlc_guid_to_string(omlc_get_guid(*value), buf);
        break;
    case OML_BOOL_VALUE:
        n += snprintf(buf, size, "%s", (omlc_get_bool(*value)==OMLC_BOOL_FALSE) ? "false" : "true");
        break;
    case OML_VECTOR_DOUBLE_VALUE:
        m = omlc_get_vector_nof_elts(*value);
        n += snprintf(buf, size, "%zu", m);
        for(i = 0; i < m && n < size; i++)
            n += snprintf(&buf[n], size - n, " %.*g", DBL_DIG, ((double*)(omlc_get_vector_ptr(*value)))[i]);
        break;
    case OML_VECTOR_INT32_VALUE:
        m = omlc_get_vector_nof_elts(*value);
        n += snprintf(buf, size, "%zu", m);
        for(i = 0; i < m && n < size; i++)
            n += snprintf(&buf[n], size - n, " %" PRId32, ((int32_t*)(omlc_get_vector_ptr(*value)))[i]);
        break;
    case OML_VECTOR_UINT32_VALUE:
        m = omlc_get_vector_nof_elts(*value);
        n += snprintf(buf, size, "%zu", m);
        for(i = 0; i < m && n < size; i++)
            n += snprintf(&buf[n], size - n, " %" PRIu32, ((uint32_t*)(omlc_get_vector_ptr(*value)))[i]);
        break;
    case OML_VECTOR_INT64_VALUE:
        m = omlc_get_vector_nof_elts(*value);
        n += snprintf(buf, size, "%zu", m);
        for(i = 0; i < m && n < size; i++)
            n += snprintf(&buf[n], size - n, " %" PRId64, ((int64_t*)(omlc_get_vector_ptr(*value)))[i]);
        break;
    case OML_VECTOR_UINT64_VALUE:
        m = omlc_get_vector_nof_elts(*value);
        n += snprintf(buf, size, "%zu", m);
        for(i = 0; i < m && n < size; i++)
            n += snprintf(&buf[n], size - n, " %" PRIu64, ((uint64_t*)(omlc_get_vector_ptr(*value)))[i]);
        break;
    case OML_VECTOR_BOOL_VALUE:
        m = omlc_get_vector_nof_elts(*value);
        n += snprintf(buf, size, "%zu", m);
        for(i = 0; i < m && n < size; i++)
            n += snprintf(&buf[n], size - n, " %s", ((bool*)(omlc_get_vector_ptr(*value)))[i] ? "true" : "false");
        break;
    default:
        logerror("%s() for type '%d' not implemented'\n", __FUNCTION__, type);
        return NULL;
    }

    /* Ensure string is NUL-terminated... */
    if(n < size)
        buf[n] = '\0';
    else {
        /* Indicate truncation when space permits */
        const char ldots[] = "...";
        const size_t ldots_sz = sizeof(ldots);
        if(ldots_sz < size)
            strcpy(buf + size - ldots_sz, ldots);
        else
            buf[size] = '\0';
    }

    return buf;
}
Esempio n. 5
0
/** Read the marshalling header information contained in an MBuffer.
 *
 * \param mbuf MBuffer to read from
 * \param header pointer to an OmlBinaryHeader into which the data from the
 *               mbuf should be unmarshalled
 * \return 1 on success, the size of the missing section as a negative number
 *         if the buffer is too short, or 0 if something failed
 */
int
unmarshal_init(MBuffer* mbuf, OmlBinaryHeader* header)
{
  uint8_t header_str[PACKET_HEADER_SIZE + 2];
  uint8_t stream_header_str[STREAM_HEADER_SIZE];
  int result, n;
  OmlValue seqno;
  OmlValue timestamp;

  oml_value_init(&seqno);
  oml_value_init(&timestamp);

  result = mbuf_begin_read (mbuf);
  if (result == -1) {
    logerror("Couldn't start unmarshalling packet (mbuf_begin_read())\n");
    return 0;
  }

  result = mbuf_read (mbuf, header_str, 3);
  if (result == -1) {
    return mbuf_rd_remaining (mbuf) - 3;
  }

  if (! (header_str[0] == SYNC_BYTE && header_str[1] == SYNC_BYTE)) {
    logdebug("Cannot find sync bytes in binary stream, out of sync; first 3 bytes: %#0x %#0x %#0x\n",
        header_str[0], header_str[1], header_str[2]);
    return 0;
  }

  header->type = (OmlBinMsgType)header_str[2];

  if (header->type == OMB_DATA_P) {
    // Read 2 more bytes of the length field
    uint16_t nv16 = 0;
    result = mbuf_read (mbuf, (uint8_t*)&nv16, sizeof (uint16_t));
    if (result == -1) {
      n = mbuf_rd_remaining (mbuf) - 2;
      mbuf_reset_read (mbuf);
      return n;
    }
    header->length = (int)ntohs (nv16);
  } else if (header->type == OMB_LDATA_P) {
    // Read 4 more bytes of the length field
    uint32_t nv32 = 0;
    result = mbuf_read (mbuf, (uint8_t*)&nv32, sizeof (uint32_t));
    if (result == -1) {
      n = mbuf_rd_remaining (mbuf) - 4;
      mbuf_reset_read (mbuf);
      return n;
    }
    header->length = (int)ntohl (nv32);
  } else {
    logwarn ("Unknown packet type %d\n", (int)header->type);
    return 0;
  }

  int extra = mbuf_rd_remaining (mbuf) - header->length;
  if (extra < 0) {
    mbuf_reset_read (mbuf);
    return extra;
  }

  result = mbuf_read (mbuf, stream_header_str, LENGTH (stream_header_str));
  if (result == -1) {
      n = mbuf_rd_remaining (mbuf) - LENGTH (stream_header_str);
      mbuf_reset_read (mbuf);
      return n;
  }

  header->values = (int)stream_header_str[0];
  header->stream = (int)stream_header_str[1];

  if (unmarshal_typed_value (mbuf, "seq-no", OML_INT32_VALUE, &seqno) == -1)
    return 0;

  if (unmarshal_typed_value (mbuf, "timestamp", OML_DOUBLE_VALUE, &timestamp) == -1)
    return 0;

  header->seqno = omlc_get_int32(*oml_value_get_value(&seqno));
  header->timestamp = omlc_get_double(*oml_value_get_value(&timestamp));

  oml_value_reset(&seqno);
  oml_value_reset(&timestamp);

  return 1;
}
Esempio n. 6
0
/** Marshal a single OmlValueU of type OmlValueT into mbuf.
 *
 * Usually called by marshal_values(). On failure, the whole message writing is
 * reset using mbuf_reset_write(), and marshalling should restart with
 * marshal_init(), after the MBuffer has been adequately resized or repacked.
 *
 * \param mbuf MBuffer to write marshalled data to
 * \param val_type OmlValueT representing the type of val
 * \param val pointer to OmlValueU, of type val_type, to marshall
 * \return 1 on success, or 0 otherwise (marshalling should then restart from marshal_init())
 * \see marshal_values, marshal_init, mbuf_reset_write, mbuf_repack_message, mbuf_repack_message2, mbuf_resize
 */
int
marshal_value(MBuffer* mbuf, OmlValueT val_type, OmlValueU* val)
{
  switch (val_type) {
  case OML_LONG_VALUE: {
    long v = oml_value_clamp_long (omlc_get_long(*val));
    uint32_t uv = (uint32_t)v;
    uint32_t nv = htonl(uv);
    uint8_t buf[LONG_T_SIZE+1];

    buf[0] = LONG_T;
    memcpy(&buf[1], &nv, sizeof (nv));

    logdebug3("Marshalling long %ld\n", nv);
    int result = mbuf_write (mbuf, buf, LENGTH (buf));
    if (result == -1) {
      logerror("Failed to marshal OML_LONG_VALUE (mbuf_write())\n");
      mbuf_reset_write (mbuf);
      return 0;
    }
    break;
  }
  case OML_INT32_VALUE:
  case OML_UINT32_VALUE:
  case OML_INT64_VALUE:
  case OML_UINT64_VALUE: {
    uint8_t buf[UINT64_T_SIZE+1]; // Max integer size
    uint32_t uv32;
    uint32_t nv32;
    uint64_t uv64;
    uint64_t nv64;
    uint8_t *p_nv;

    if (oml_size_map[val_type] == 4)
    {
      uv32 = omlc_get_uint32(*val);
      nv32 = htonl(uv32);
      p_nv = (uint8_t*)&nv32;
      logdebug3("Marshalling %s %" PRIu32 "\n", oml_type_to_s(val_type), uv32);
    } else {
      uv64 = omlc_get_uint64(*val);
      nv64 = htonll(uv64);
      p_nv = (uint8_t*)&nv64;
      logdebug3("Marshalling %s %" PRIu64 "\n", oml_type_to_s(val_type), uv64);
    }

    buf[0] = oml_type_map[val_type];
    memcpy(&buf[1], p_nv, oml_size_map[val_type]);

    int result = mbuf_write (mbuf, buf, oml_size_map[val_type] + 1);
    if (result == -1)
      {
        logerror("Failed to marshal %s value (mbuf_write())\n",
               oml_type_to_s (val_type));
        mbuf_reset_write (mbuf);
        return 0;
      }
    break;
  }
  case OML_DOUBLE_VALUE: {
    uint8_t type = DOUBLE_T;
    double v = omlc_get_double(*val);
    int exp;
    double mant = frexp(v, &exp);
    int8_t nexp = (int8_t)exp;
    logdebug3("Marshalling double %f\n", v);
    if (isnan(v)) {
      type = DOUBLE_NAN;
      nexp = 0;
      mant = 0;
    } else if (nexp != exp) {
      logerror("Double number '%lf' is out of bounds, sending NaN\n", v);
      type = DOUBLE_NAN;
      nexp = 0;
      mant = 0;
   }
   int32_t imant = (int32_t)(mant * (1 << BIG_L));
   uint32_t nmant = htonl(imant);

   uint8_t buf[6] = { type, 0, 0, 0, 0, nexp };

   memcpy(&buf[1], &nmant, sizeof (nmant));

   int result = mbuf_write (mbuf, buf, LENGTH (buf));

   if (result == -1)
     {
       logerror("Failed to marshal OML_DOUBLE_VALUE (mbuf_write())\n");
       mbuf_reset_write (mbuf);
       return 0;
     }
   break;
 }
 case OML_STRING_VALUE: {
   char* str = omlc_get_string_ptr(*val);

   if (str == NULL) {
     str = "";
     logdebug("Attempting to send a NULL string; sending empty string instead\n");
   }

   size_t len = strlen(str);
   if (len > STRING_T_MAX_SIZE) {
     logerror("Truncated string '%s'\n", str);
     len = STRING_T_MAX_SIZE;
   }

   logdebug3("Marshalling string '%s' of length %d\n", str, len);
   uint8_t buf[2] = { STRING_T, (uint8_t)(len & 0xff) };
   int result = mbuf_write (mbuf, buf, LENGTH (buf));
   if (result == -1) {
     logerror("Failed to marshal OML_STRING_VALUE type and length (mbuf_write())\n");
     mbuf_reset_write (mbuf);
     return 0;
   }

   result = mbuf_write (mbuf, (uint8_t*)str, len);

   if (result == -1)
     {
       logerror("Failed to marshal OML_STRING_VALUE (mbuf_write())\n");
       mbuf_reset_write (mbuf);
       return 0;
     }
   break;
 }
 case OML_BLOB_VALUE: {
   int result = 0;
   void *blob = omlc_get_blob_ptr(*val);
   size_t length = omlc_get_blob_length(*val);
   if (blob == NULL || length == 0) {
     logdebug ("Attempting to send NULL or empty blob; blob of length 0 will be sent\n");
     length = 0;
   }

   uint8_t buf[5] = { BLOB_T, 0, 0, 0, 0 };
   size_t n_length = htonl (length);
   memcpy (&buf[1], &n_length, 4);

   logdebug3("Marshalling blob of size %d\n", length);
   result = mbuf_write (mbuf, buf, sizeof (buf));

   if (result == -1) {
     logerror ("Failed to marshall OML_BLOB_VALUE type and length (mbuf_write())\n");
     mbuf_reset_write (mbuf);
     return 0;
   }

   result = mbuf_write (mbuf, blob, length);

   if (result == -1) {
     logerror ("Failed to marshall %d bytes of OML_BLOB_VALUE data\n", length);
     mbuf_reset_write (mbuf);
     return 0;
   }
   break;
 }

  case OML_GUID_VALUE: {
    /* FIXME: Wrap with UINT64 marshalling, just change the type */
    uint64_t nv64;
    uint8_t buf[GUID_T_SIZE+1];
    buf[0] = GUID_T;
    nv64 = htonll(omlc_get_guid(*val));
    memcpy(&buf[1], &nv64, sizeof(nv64));
    logdebug3("Marshalling GUID %" PRIu64 "\n", nv64);
    if (-1 == mbuf_write(mbuf, buf, LENGTH(buf))) {
      logerror("Failed to marshal OML_GUID_VALUE (mbuf_write())\n");
      mbuf_reset_write(mbuf);
      return 0;
    }
    break;
  }

  case OML_BOOL_VALUE: {
    uint8_t buf;
    if (!omlc_get_bool(*val)) {
      buf = BOOL_FALSE_T;
    } else {
      buf = BOOL_TRUE_T;
    }
    logdebug3("Marshalling boolean %d\n", BOOL_TRUE_T == buf);
    if (-1 == mbuf_write(mbuf, &buf, 1)) {
      logerror("Failed to marshal OML_BOOL_VALUE (mbuf_write())\n");
      mbuf_reset_write(mbuf);
      return 0;
    }
    break;
  }

  case OML_VECTOR_INT32_VALUE:
  case OML_VECTOR_UINT32_VALUE: {
    size_t i;
    uint8_t buf[VECTOR_T_SIZE] = { VECTOR_T, 0, 0, 0 };
    uint16_t hn = omlc_get_vector_nof_elts(*val);
    uint16_t nn = htons(hn);
    buf[1] = vector_protocol_map[val_type];
    memcpy(&buf[2], &nn, sizeof(nn));
    if(mbuf_write(mbuf, buf, VECTOR_T_SIZE) == 0) {
      uint32_t elts[hn];
      uint32_t *v = omlc_get_vector_ptr(*val);
      for(i = 0; i < hn; i++)
        elts[i] = htonl(*((uint32_t*)(v+i)));
      if(mbuf_write(mbuf, (const uint8_t*)(elts), sizeof(elts)) == -1) {
        logerror("%s(): failed to marshal %s of size %" PRIu16 " (mbuf_write())\n", __func__, oml_type_to_s(val_type), hn);
        mbuf_reset_write(mbuf);
        return 0;
      }
    } else {
      logerror("%s(): failed to marshal %s length (mbuf_write())\n", __func__, oml_type_to_s(val_type));
      mbuf_reset_write(mbuf);
      return 0;
    }
    break;
  }

  case OML_VECTOR_INT64_VALUE:
  case OML_VECTOR_UINT64_VALUE:
  case OML_VECTOR_DOUBLE_VALUE: {
    size_t i;
    uint8_t buf[VECTOR_T_SIZE] = { VECTOR_T, 0, 0, 0 };
    uint16_t hn = omlc_get_vector_nof_elts(*val);
    uint16_t nn = htons(hn);
    buf[1] = vector_protocol_map[val_type];
    memcpy(&buf[2], &nn, sizeof(nn));
    if(mbuf_write(mbuf, buf, VECTOR_T_SIZE) == 0) {
      uint64_t elts[hn];
      uint64_t *v = omlc_get_vector_ptr(*val);
      for(i = 0; i < hn; i++)
        elts[i] = htonll(*((uint64_t*)(v+i)));
      if(mbuf_write(mbuf, (const uint8_t*)(elts), sizeof(elts)) == -1) {
        logerror("%s(): failed to marshal %s of size %" PRIu16 " (mbuf_write())\n", __func__, oml_type_to_s(val_type), hn);
        mbuf_reset_write(mbuf);
        return 0;
      }
    } else {
      logerror("%s(): failed to marshal %s length (mbuf_write())\n", __func__, oml_type_to_s(val_type));
      mbuf_reset_write(mbuf);
        return 0;
    }
    break;
  }

  case OML_VECTOR_BOOL_VALUE: {
    size_t i;
    uint8_t buf[VECTOR_T_SIZE] = { VECTOR_T, 0, 0, 0 };
    uint16_t hn = omlc_get_vector_nof_elts(*val);
    uint16_t nn = htons(hn);
    buf[1] = vector_protocol_map[val_type];
    memcpy(&buf[2], &nn, sizeof(nn));
    if(mbuf_write(mbuf, buf, VECTOR_T_SIZE) == 0) {
      uint8_t elts[hn];
      bool *v = omlc_get_vector_ptr(*val);
      for(i = 0; i < hn; i++)
        elts[i] = v[i] ? BOOL_TRUE_T : BOOL_FALSE_T;
      if(mbuf_write(mbuf, (const uint8_t*)(elts), hn) == -1) {
        logerror("%s(): failed to marshal %s of size %" PRIu16 " (mbuf_write())\n", __func__, oml_type_to_s(val_type), hn);
        mbuf_reset_write(mbuf);
        return 0;
      }
    } else {
      logerror("%s(): failed to marshal %s length (mbuf_write())\n", __func__, oml_type_to_s(val_type));
      mbuf_reset_write(mbuf);
      return 0;
    }
    break;
  }

  default:
    logerror("%s(): Unsupported value type '%d'\n", __func__, val_type);
    return 0;
  }

  return 1;
}
Esempio n. 7
0
/** Unmarshals the next content of an MBuffer into a OmlValue
 *
 * \param mbuf MBuffer to read from
 * \param value pointer to OmlValue to unmarshall the read data into
 * \return 1 if successful, 0 otherwise
 */
int
unmarshal_value(MBuffer *mbuf, OmlValue *value)
{
  if (mbuf_rd_remaining(mbuf) == 0) {
    logerror("Tried to unmarshal a value from the buffer, but didn't receive enough data to do that\n");
    return 0;
  }

  int type = mbuf_read_byte (mbuf);
  if (type == -1) return 0;

  switch (type) {
  case LONG_T: {
    uint8_t buf [LONG_T_SIZE];

    if (mbuf_read (mbuf, buf, LENGTH (buf)) == -1)
    {
      logerror("Failed to unmarshal OML_LONG_VALUE; not enough data?\n");
      return 0;
    }

    uint32_t hv = ntohl(*((uint32_t*)buf));
    int32_t v = (int32_t)(hv);

    /*
     * The server no longer needs to know about OML_LONG_VALUE, as the
     * marshalling process now maps OML_LONG_VALUE into OML_INT32_VALUE
     * (by truncating to [INT_MIN, INT_MAX].  Therefore, unmarshall a
     * LONG_T value into an OML_INT32_VALUE object.
     */
    oml_value_set_type(value, OML_INT32_VALUE);
    omlc_set_int32(*oml_value_get_value(value), v);
    break;
  }
  case INT32_T:
  case UINT32_T:
  case INT64_T:
  case UINT64_T: {
    uint8_t buf [UINT64_T_SIZE]; // Maximum integer size
    OmlValueT oml_type = protocol_type_map[type];
    if (mbuf_read (mbuf, buf, protocol_size_map[type]) == -1) {
      logerror("Failed to unmarshall %d value; not enough data?\n", type);
      return 0;
    }
    oml_value_set_type(value, oml_type);
    switch (type) {
    case INT32_T:
      omlc_set_int32(*oml_value_get_value(value), ntohl(*((int32_t*)buf)));
      logdebug3("Unmarshalled %s %" PRId32 "\n", oml_type_to_s(oml_type), omlc_get_int32(*oml_value_get_value(value)));
      break;

    case UINT32_T:
      omlc_set_uint32(*oml_value_get_value(value), ntohl(*((uint32_t*)buf)));
      logdebug3("Unmarshalled %s %" PRIu32 "\n", oml_type_to_s(oml_type), omlc_get_uint32(*oml_value_get_value(value)));
      break;

    case INT64_T:
      omlc_set_int64(*oml_value_get_value(value), ntohll(*((int64_t*)buf)));
      logdebug3("Unmarshalled %s %" PRId64 "\n", oml_type_to_s(oml_type), omlc_get_int64(*oml_value_get_value(value)));
      break;

    case UINT64_T:
      omlc_set_uint64(*oml_value_get_value(value), ntohll(*((uint64_t*)buf)));
      logdebug3("Unmarshalled %s %" PRIu64 "\n", oml_type_to_s(oml_type), omlc_get_uint64(*oml_value_get_value(value)));
      break;

    default:
      logerror("Integer morphed, something magic has just happened\n");
      return 0;
    }
    break;
  }
  case DOUBLE_T: {
    uint8_t buf [DOUBLE_T_SIZE];
    OmlValueT oml_type = protocol_type_map[type];
    if (mbuf_read (mbuf, buf, LENGTH (buf)) == -1)
    {
      logerror("Failed to unmarshal OML_DOUBLE_VALUE; not enough data?\n");
      return 0;
    }

    int hmant = (int)ntohl(*((uint32_t*)buf));
    double mant = hmant * 1.0 / (1 << BIG_L);
    int exp = (int8_t) buf[4];
    double v = ldexp(mant, exp);
    oml_value_set_type(value, oml_type);
    omlc_set_double(*oml_value_get_value(value), v);
    logdebug3("Unmarshalled double %f\n", omlc_get_double(*oml_value_get_value(value)));
    break;
  }
  case DOUBLE_NAN: {
    OmlValueT oml_type = protocol_type_map[type];
    mbuf_read_skip(mbuf, DOUBLE_T_SIZE); /* The data is irrelevant */
    oml_value_set_type(value, oml_type);
    omlc_set_double(*oml_value_get_value(value), NAN);
    logdebug("Received NaN\n");
    break;
  }
  case STRING_T: {
    int len = 0;
    uint8_t buf [STRING_T_MAX_SIZE];

    len = mbuf_read_byte (mbuf);

    if (len == -1 || mbuf_read (mbuf, buf, len) == -1)
    {
      logerror("Failed to unmarshal OML_STRING_VALUE; not enough data?\n");
      return 0;
    }

    oml_value_set_type(value, OML_STRING_VALUE);
    omlc_set_string_copy(*oml_value_get_value(value), buf, len);
    logdebug3("Unmarshalled string '%s' of length %d\n", omlc_get_string_ptr(*oml_value_get_value(value)), len);
    break;
  }
  case BLOB_T: {
    uint32_t n_len;

    if (mbuf_read (mbuf, (uint8_t*)&n_len, 4) == -1) {
      logerror ("Failed to unmarshal OML_BLOB_VALUE length field; not enough data?\n");
      return 0;
    }

    size_t len = ntohl (n_len);
    size_t remaining = mbuf_rd_remaining (mbuf);

    if (len > remaining) {
      logerror ("Failed to unmarshal OML_BLOB_VALUE data:  not enough data available "
                "(wanted %d, but only have %d bytes\n",
                len, remaining);
      return 0;
    }

    void *ptr = mbuf_rdptr (mbuf);
    oml_value_set_type(value, OML_BLOB_VALUE);
    omlc_set_blob (*oml_value_get_value(value), ptr, len); /*XXX*/
    logdebug3("Unmarshalled blob of size %d\n", len);
    mbuf_read_skip (mbuf, len);
    break;
  }

  case GUID_T: {
    uint64_t nv64;
    uint8_t buf[GUID_T_SIZE];
    if(mbuf_read(mbuf, buf, GUID_T_SIZE) == -1) {
      logerror("Failed to unmarshall OML_GUID_VALUE data; not enough data?\n");
      return 0;
    }
    memcpy(&nv64, buf, sizeof(nv64));
    oml_value_set_type(value, OML_GUID_VALUE);
    omlc_set_guid(*oml_value_get_value(value), ntohll(nv64));
    logdebug3("Unmarshalled GUID %" PRIu64 "\n", omlc_get_guid(*oml_value_get_value(value)));
    break;
  }

  case BOOL_FALSE_T:
  case BOOL_TRUE_T:
    oml_value_set_type(value, OML_BOOL_VALUE);
    omlc_set_bool(*oml_value_get_value(value),
                  (type == BOOL_TRUE_T)?OMLC_BOOL_TRUE:OMLC_BOOL_FALSE);
    logdebug3("Unmarshalled boolean %d\n", OMLC_BOOL_TRUE == omlc_get_bool(*oml_value_get_value(value)));
    break;

  case VECTOR_T: {
    uint16_t i, nof_elts;
    int type = mbuf_read_byte(mbuf);
    if(-1 == type) {
      logerror("%s(): failed to unmarshall VECTOR_T length\n", __func__);
      return 0;
    }
    if(mbuf_read(mbuf,(uint8_t*)(&nof_elts), sizeof(nof_elts)) == -1) {
      logerror("%s(): failed to unmarshall VECTOR_T length\n", __func__);
      return 0;
    }
    nof_elts = ntohs(nof_elts);

    OmlValueT oml_type = vector_type_map[type];
    OmlValueU *v = oml_value_get_value(value);
    switch(type) {
    case INT32_T:
    case UINT32_T: {
      size_t bytes = nof_elts * sizeof(uint32_t);
      uint32_t *elts = oml_calloc(nof_elts, sizeof(uint32_t));
      if(mbuf_read(mbuf, (uint8_t*)(elts), nof_elts * sizeof(uint32_t)) == -1) {
        logerror("%s(): failed to unmarshall OML_VECTOR_(U)INT32_VALUE\n", __func__);
        return 0;
      }
      for(i = 0; i < nof_elts; i++)
        elts[i] = ntohl(elts[i]);
      oml_value_set_type(value, oml_type);
      omlc_set_vector_ptr(*v, elts);
      omlc_set_vector_length(*v, bytes);
      omlc_set_vector_size(*v, bytes);
      omlc_set_vector_nof_elts(*v, nof_elts);
      omlc_set_vector_elt_size(*v, sizeof(uint32_t));
      break;
    }
    case INT64_T:
    case UINT64_T:
    case DOUBLE64_T: {
      size_t bytes = nof_elts * sizeof(uint64_t);
      uint64_t *elts = oml_calloc(nof_elts, sizeof(uint64_t));
      if(mbuf_read(mbuf, (uint8_t*)(elts), nof_elts * sizeof(uint64_t)) == -1) {
        logerror("%s(): failed to unmarshall OML_VECTOR_(U)INT64_VALUE\n", __func__);
        return 0;
      }
      for(i = 0; i < nof_elts; i++)
        elts[i] = ntohll(elts[i]);
      oml_value_set_type(value, oml_type);
      omlc_set_vector_ptr(*v, elts);
      omlc_set_vector_length(*v, bytes);
      omlc_set_vector_size(*v, bytes);
      omlc_set_vector_nof_elts(*v, nof_elts);
      omlc_set_vector_elt_size(*v, sizeof(uint64_t));
      break;
    }
    case BOOL_T: {
      uint8_t y[nof_elts];
      size_t bytes = nof_elts * sizeof(bool);
      bool *elts = oml_calloc(nof_elts, sizeof(bool));
      if(mbuf_read(mbuf, y, nof_elts) == -1) {
        logerror("%s(): failed to unmarshall OML_VECTOR_BOOL_VALUE\n", __func__);
        return 0;
      }
      for(i = 0; i < nof_elts; i++)
        elts[i] = ((BOOL_TRUE_T == y[i]) ? true : false);
      oml_value_set_type(value, oml_type);
      omlc_set_vector_ptr(*v, elts);
      omlc_set_vector_length(*v, bytes);
      omlc_set_vector_size(*v, bytes);
      omlc_set_vector_nof_elts(*v, nof_elts);
      omlc_set_vector_elt_size(*v, sizeof(bool));
      break;
    }
    default:
      logerror("%s(): bad type for array (t=%d)\n", __func__, type);
      break;
    }
    break;
  }

  default:
    logerror("%s: Unsupported value type '%d'\n", __FUNCTION__, type);
    return 0;
  }

  return 1;
}