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
File: text.c Progetto: mytestbed/oml
/**
 *  @brief Read a vector of values matching schema from mbuf.
 *
 *  Reads as many values as required to match the schema from the
 *  mbuf, and stores them in the values vector.
 *
 */
int
text_read_msg_values (struct oml_message *msg, MBuffer *mbuf, struct schema *schema, OmlValue *values)
{
  int length = msg->length;
  int index = mbuf_message_index (mbuf);
  int msg_remaining = length - index;
  int i = 0;

  length = msg_remaining;

  for (i = 0; i < schema->nfields; i++) {
    int bytes;
    oml_value_set_type(&values[i], schema->fields[i].type);
    bytes = text_read_value (mbuf, &values[i], length);

    if (bytes == -1)
      return -1;
    else
      length -= bytes;
  }

  msg->count = schema->nfields;
  // rdptr now points to start of next line/message
  mbuf_consume_message (mbuf);
  return 0;
}
Esempio n. 3
0
/** Try to convert a string to the type represented by the given string, and store it an OmlValue.
 *
 * \param value pointer to output OmlValue
 * \param type_s string representing an OmlValueT
 * \param value_s input string
 * \return  0 on success, -1 otherwise
 * \see oml_value_init, oml_value_ut_from_s, oml_type_from_s
 */
int
oml_value_from_typed_s (OmlValue *value, const char *type_s, const char *value_s)
{
    OmlValueT type = oml_type_from_s (type_s);
    oml_value_set_type(value, type);
    return oml_value_ut_from_s(oml_value_get_value(value), type, value_s);
}
Esempio n. 4
0
END_TEST

START_TEST (test_blob)
{
  char *str = "this is a string subtly disguised as a blob";
  OmlValue v, v2;
  OmlValueU vu;
  size_t len = strlen(str);
  void *test = (void*)str;
  size_t bcount;
  size_t alloc_diff;

  oml_value_init(&v);
  oml_value_init(&v2);

  omlc_zero(vu);

  /* Prepare the OmlValueU to be duplicated in the OmlValue */
  omlc_set_blob(vu, test, len);
  bcount = xmembytes();

  oml_value_set(&v, &vu, OML_BLOB_VALUE);
  alloc_diff = xmembytes() - bcount - sizeof(size_t);
  bcount = xmembytes();
  fail_if(alloc_diff < len,
      "OmlValue blob allocated memory not big enough (%d instead of at least %d)",
      alloc_diff, len);

  oml_value_duplicate(&v2, &v);
  fail_if(omlc_get_blob_ptr(*oml_value_get_value(&v2)) == omlc_get_blob_ptr(*oml_value_get_value(&v)),
      "Copied OmlValue blob pointer not allocated properly");
  fail_if(strncmp(omlc_get_blob_ptr(*oml_value_get_value(&v2)), omlc_get_blob_ptr(*oml_value_get_value(&v)), len),
      "Copied OmlValue blob mismatch");
  fail_unless(omlc_get_blob_length(*oml_value_get_value(&v2)) == omlc_get_blob_length(*oml_value_get_value(&v)),
      "Copied OmlValue blob length not set properly (%d instead of %d)",
      omlc_get_blob_length(*oml_value_get_value(&v2)), omlc_get_blob_length(*oml_value_get_value(&v2)));
  alloc_diff = xmembytes() - bcount - sizeof(size_t); /* oml_malloc() always allocates at least sizeof(size_t) more for bookkeeping */
  bcount = xmembytes();
  fail_if(alloc_diff < len,
      "Copied OmlValue blob allocated memory not big enough (%d instead of at least %d)",
      alloc_diff, len);
  fail_unless(omlc_get_blob_size(*oml_value_get_value(&v2)) == oml_malloc_usable_size(omlc_get_blob_ptr(*oml_value_get_value(&v2))),
      "Copied OmlValue blob allocated size not set properly (%d instead of %d)",
      omlc_get_blob_size(*oml_value_get_value(&v2)), oml_malloc_usable_size(omlc_get_blob_ptr(*oml_value_get_value(&v2))));

  oml_value_set_type(&v, OML_UINT64_VALUE);
  fail_unless(xmembytes() < bcount,
      "OmlValue blob  was not freed after oml_value_set_type() (%d allocated, which is not less than %d)",
      xmembytes(), bcount);
  bcount = xmembytes();

  oml_value_reset(&v2);
  fail_unless(xmembytes() < bcount,
      "OmlValue blob  was not freed after oml_value_reset() (%d allocated, which is not less than %d)",
      xmembytes(), bcount);
  bcount = xmembytes();

  oml_value_reset(&v);
  omlc_reset_blob(vu);
}
Esempio n. 5
0
END_TEST

START_TEST (test_string)
{
  char *test = "test";
  OmlValue v, v2;
  OmlValueU vu;
  size_t bcount = xmembytes();
  size_t alloc_diff;

  oml_value_init(&v);
  oml_value_init(&v2);

  omlc_zero(vu);

  /* Prepare the OmlValueU to be duplicated in the OmlValue */
  omlc_set_const_string(vu, test);

  oml_value_set(&v, &vu, OML_STRING_VALUE);
  alloc_diff = xmembytes() - bcount - sizeof(size_t);
  bcount = xmembytes();
  fail_if(alloc_diff < strlen(test) + 1,
      "OmlValue string allocated memory not big enough (%d instead of at least %d)",
      alloc_diff, strlen(test) + 1);

  oml_value_duplicate(&v2, &v);
  fail_if(omlc_get_string_ptr(*oml_value_get_value(&v2)) == omlc_get_string_ptr(*oml_value_get_value(&v)),
      "Copied OmlValue string pointer not allocated properly");
  fail_if(strcmp(omlc_get_string_ptr(*oml_value_get_value(&v2)), omlc_get_string_ptr(*oml_value_get_value(&v))),
      "Copied OmlValue string mismatch ('%s' instead of '%s')",
      omlc_get_string_ptr(*oml_value_get_value(&v2)), omlc_get_string_ptr(*oml_value_get_value(&v)));
  fail_unless(omlc_get_string_length(*oml_value_get_value(&v2)) == strlen(omlc_get_string_ptr(*oml_value_get_value(&v2))),
      "Copied OmlValue string length not set properly (%d instead of %d)",
      omlc_get_string_length(*oml_value_get_value(&v2)), strlen(omlc_get_string_ptr(*oml_value_get_value(&v2))) + 1);
  alloc_diff = xmembytes() - bcount - sizeof(size_t); /* oml_malloc() always allocates at least sizeof(size_t) more for bookkeeping */
  bcount = xmembytes();
  fail_if(alloc_diff < strlen(omlc_get_string_ptr(*oml_value_get_value(&v))) + 1,
      "Copied OmlValue string allocated memory not big enough (%d instead of at least %d)",
      alloc_diff, strlen(omlc_get_string_ptr(*oml_value_get_value(&v))) + 1);
  fail_unless(omlc_get_string_size(*oml_value_get_value(&v2)) == oml_malloc_usable_size(omlc_get_string_ptr(*oml_value_get_value(&v2))),
      "Copied OmlValue string allocated size not set properly (%d instead of %d)",
      omlc_get_string_size(*oml_value_get_value(&v2)), oml_malloc_usable_size(omlc_get_string_ptr(*oml_value_get_value(&v2))));
  fail_unless(omlc_get_string_is_const(*oml_value_get_value(&v2)) == 0,
      "Copied OmlValue string should not be constant");

  oml_value_set_type(&v, OML_UINT64_VALUE);
  fail_unless(xmembytes() < bcount,
      "OmlValue string  was not freed after oml_value_set_type() (%d allocated, which is not less than %d)",
      xmembytes(), bcount);
  bcount = xmembytes();

  oml_value_reset(&v2);
  fail_unless(xmembytes() < bcount,
      "OmlValue string  was not freed after oml_value_reset() (%d allocated, which is not less than %d)",
      xmembytes(), bcount);
  bcount = xmembytes();

  oml_value_reset(&v);
  omlc_reset_string(vu);
}
Esempio n. 6
0
/** Assign the content of an OmlValueU of the given OmlValueT to an OmlValue.
 *
 * This function copies value, which is assumed to be of the given type (no
 * check can be made), into the OmlValue pointed to by to.  The to object is
 * set to have the given type. If type is a simple numeric type, the copy
 * simply copies the value.
 *
 * If type is OML_STRING_VALUE, then the string contents are copied into new
 * storage in to.  If to was previously set to be a const string, then the
 * is_const flag is cleared and a new block of memory is allocated to store the
 * copy and its terminating null character. If to did not previously have the
 * is_const flag set, and its string pointer was NULL, then a new block of
 * memory is also allocated as well.  If the string pointer was not NULL, then
 * the string is copied into the previously allocated memory block if it is
 * large enough to fit; otherwise the block is freed and a new one allocated
 * large enough to hold the string (and its terminator).
 *
 * Blobs are handled in a similar fashion.
 *
 * If the source pointer is NULL then an error is returned and a warning
 * message is sent to the log.
 *
 * \param to pointer to OmlValue into which the value should be copied
 * \param value pointer to original OmlValueU to copy into to
 * \param type OmlValueT of value
 * \return 0 if successful, -1 otherwise
 * \see oml_value_init, omlc_copy_string, omlc_copy_blob
 */
int
oml_value_set(OmlValue *to, const OmlValueU *value, OmlValueT type)
{
    oml_value_set_type(to, type);
    if (omlc_is_numeric_type (type) ||
            omlc_is_guid_type (type) ||
            omlc_is_bool_type (type)) {
        to->value = *value;
    } else {
        switch (type) {
        case OML_STRING_VALUE:
            if (!omlc_get_string_ptr(*value)) {
                logwarn("Trying to copy OML_STRING_VALUE from a NULL source\n");
                return -1;
            }
            omlc_copy_string(*oml_value_get_value(to), *value);
            break;

        case OML_DATETIME_VALUE:
            if (!omlc_get_string_ptr(*value)) {
                logwarn("Trying to copy OML_DATETIME_VALUE from a NULL source\n");
                return -1;
            }
            omlc_copy_string(*oml_value_get_value(to), *value);
            break;

        case OML_BLOB_VALUE:
            if (!omlc_get_blob_ptr(*value)) {
                logwarn("Trying to copy OML_BLOB_VALUE from a NULL source\n");
                return -1;
            }
            omlc_copy_blob(*oml_value_get_value(to), *value);
            break;

        case OML_VECTOR_DOUBLE_VALUE:
        case OML_VECTOR_INT32_VALUE:
        case OML_VECTOR_UINT32_VALUE:
        case OML_VECTOR_INT64_VALUE:
        case OML_VECTOR_UINT64_VALUE:
        case OML_VECTOR_BOOL_VALUE:
            if (!omlc_get_vector_ptr(*value)) {
                logwarn("Trying to copy OML_VECTOR_*_VALUE from a NULL source\n");
                return -1;
            }
            omlc_copy_vector(*oml_value_get_value(to), *value);
            break;

        default:
            logerror("%s() for type '%d' not implemented'\n", __FUNCTION__, type);
            return -1;
        }
    }
    return 0;
}
Esempio n. 7
0
static OmlValue*
create_filter_result_vector (OmlFilterDef* def, OmlValueT type, int count)
{
  OmlValue* result = (OmlValue*)oml_malloc(count * sizeof(OmlValue));

  if (!result) {
    logerror ("Failed to allocate memory for filter result vector\n");
    return NULL;
  }

  oml_value_array_init(result, count);

  int i = 0;
  for (i = 0; i < count; i++) {
    if (def[i].type == OML_INPUT_VALUE)
      oml_value_set_type(&result[i], type);
    else
      oml_value_set_type(&result[i], def[i].type);
  }

  return result;
}
Esempio n. 8
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;
}