Ejemplo n.º 1
0
/**
 * \brief write the result inside the file
 * \param writer pointer to writer instance
 * \param values type of sample
 * \param value_count size of above array
 * \return 1 if successful, 0 otherwise
 */
static int
row_cols(OmlWriter* writer, OmlValue* values, int value_count)
{
  OmlTextWriter* self = (OmlTextWriter*)writer;
  MBuffer* mbuf;
  if ((mbuf = self->mbuf) == NULL) return 0; /* previous use of mbuf failed */

  int i;
  OmlValue* v = values;
  for (i = 0; i < value_count; i++, v++) {
    int res;
    switch (oml_value_get_type(v)) {
    case OML_LONG_VALUE: {
      res = mbuf_print(mbuf, "\t%" PRId32, oml_value_clamp_long (v->value.longValue));
      break;
    }
    case OML_INT32_VALUE:  res = mbuf_print(mbuf, "\t%" PRId32,  v->value.int32Value);  break;
    case OML_UINT32_VALUE: res = mbuf_print(mbuf, "\t%" PRIu32,  v->value.uint32Value); break;
    case OML_INT64_VALUE:  res = mbuf_print(mbuf, "\t%" PRId64,  v->value.int64Value);  break;
    case OML_UINT64_VALUE: res = mbuf_print(mbuf, "\t%" PRIu64,  v->value.uint64Value); break;
    case OML_DOUBLE_VALUE: res = mbuf_print(mbuf, "\t%f",  v->value.doubleValue); break;
    case OML_STRING_VALUE: res = mbuf_print(mbuf, "\t%s",  omlc_get_string_ptr(*oml_value_get_value(v))); break;
    case OML_BLOB_VALUE: {
      const unsigned int max_bytes = 6;
      int bytes = v->value.blobValue.length < max_bytes ? v->value.blobValue.length : max_bytes;
      int i = 0;
      res = mbuf_print(mbuf, "blob ");
      for (i = 0; i < bytes; i++) {
        res = mbuf_print(mbuf, "%02x", ((uint8_t*)v->value.blobValue.ptr)[i]);
      }
      res = mbuf_print (mbuf, " ...");
      break;
    }
    default:
      res = -1;
      logerror( "Unsupported value type '%d'\n", oml_value_get_type(v));
      return 0;
    }
    if (res < 0) {
      mbuf_reset_write(mbuf);
      self->mbuf = NULL;
      return 0;
    }
  }
  return 1;
}
Ejemplo n.º 2
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;
}