예제 #1
0
gboolean
pyorbit_marshal_any(CORBA_any *any, PyObject *value)
{
    CORBA_TypeCode tc = any->_type;
    gconstpointer buf = any->_value;

    if (tc == NULL) return FALSE;
    return marshal_value(tc, &buf, value);
}
예제 #2
0
파일: marshal.c 프로젝트: alco90/soml
/** Marshal the array of values into an MBuffer.
 *
 * Metadata of the measurement stream should already have been written
 * with marshal_measurements(). Each element of values is written with
 * marshal_value().  Finally, the number of elements in the message is
 * updated in its header, by incrementing the relevant field
 * (depending on its OmlBinMsgType) by value_count.
 *
 * If the returned number is negative, marshalling didn't finish as
 * the provided buffer was short of the number of bytes returned (when
 * multiplied by -1); the entire message has been reset (by
 * marshal_value()), and marshalling should restart with
 * marshal_init(), after the MBuffer has been adequately resized or
 * repacked.
 *
 * Once all data has been marshalled, marshal_finalize() should be
 * called to finish preparing the message.
 *
 * \param mbuf MBuffer to write marshalled data to
 * \param values array of OmlValue of length value_count
 * \param value_count length  the values array
 * \return 1 on success, or -1 otherwise (marshalling should then restart from marshal_init())
 * \see marshal_init, marshal_measurements, marshal_value, marshal_finalize, mbuf_repack_message, mbuf_repack_message2, mbuf_resize
 */
int marshal_values(MBuffer* mbuf, OmlValue* values, int value_count)
{
  OmlValue* val = values;
  int i;

  for (i = 0; i < value_count; i++, val++) {
    if(!marshal_value(mbuf, oml_value_get_type(val), oml_value_get_value(val)))
      return -1;
  }

  uint8_t* buf = mbuf_message (mbuf);
  OmlBinMsgType type = marshal_get_msgtype (mbuf);
  switch (type) {
  case OMB_DATA_P: buf[5] += value_count; break;
  case OMB_LDATA_P: buf[7] += value_count; break;
  }
  return 1;
}
예제 #3
0
static gboolean
marshal_value(CORBA_TypeCode tc, gconstpointer *val, PyObject *value)
{
    gboolean ret = FALSE;
    gint i;

    while (tc->kind == CORBA_tk_alias)
	tc = tc->subtypes[0];

    switch (tc->kind) {
    case CORBA_tk_null:
    case CORBA_tk_void:
	ret = (value == Py_None);
	break;
    case CORBA_tk_short:
	alignval(val, ORBIT_ALIGNOF_CORBA_SHORT);
	getval(val, CORBA_short) = PyInt_AsLong(value);
	advanceptr(val, sizeof(CORBA_short));
	if (!PyErr_Occurred()) ret = TRUE;
	break;
    case CORBA_tk_long:
	alignval(val, ORBIT_ALIGNOF_CORBA_LONG);
	getval(val, CORBA_long) = PyInt_AsLong(value);
	advanceptr(val, sizeof(CORBA_long));
	if (!PyErr_Occurred()) ret = TRUE;
	break;
    case CORBA_tk_ushort:
	alignval(val, ORBIT_ALIGNOF_CORBA_SHORT);
	getval(val, CORBA_unsigned_short) = PyInt_AsLong(value);
	advanceptr(val, sizeof(CORBA_unsigned_short));
	if (!PyErr_Occurred()) ret = TRUE;
	break;
    case CORBA_tk_ulong:
    case CORBA_tk_enum:
	alignval(val, ORBIT_ALIGNOF_CORBA_LONG);
	if (PyLong_Check(value))
	    getval(val, CORBA_unsigned_long) = PyLong_AsUnsignedLong(value);
	else
	    getval(val, CORBA_unsigned_long) = PyInt_AsLong(value);
	advanceptr(val, sizeof(CORBA_unsigned_long));
	if (!PyErr_Occurred()) ret = TRUE;
	break;
    case CORBA_tk_float:
	alignval(val, ORBIT_ALIGNOF_CORBA_FLOAT);
	getval(val, CORBA_float) = PyFloat_AsDouble(value);
	advanceptr(val, sizeof(CORBA_float));
	if (!PyErr_Occurred()) ret = TRUE;
	break;
    case CORBA_tk_double:
	alignval(val, ORBIT_ALIGNOF_CORBA_DOUBLE);
	getval(val, CORBA_double) = PyFloat_AsDouble(value);
	advanceptr(val, sizeof(CORBA_double));
	if (!PyErr_Occurred()) ret = TRUE;
	break;
    case CORBA_tk_boolean:
	getval(val, CORBA_boolean) = PyObject_IsTrue(value);
	advanceptr(val, sizeof(CORBA_boolean));
	if (!PyErr_Occurred()) ret = TRUE;
	break;
    case CORBA_tk_char:
	if (PyString_Check(value) && PyString_Size(value) == 1) {
	    getval(val, CORBA_char) = PyString_AsString(value)[0];
	    advanceptr(val, sizeof(CORBA_char));
	    ret = TRUE;
	}
	break;
    case CORBA_tk_octet:
	getval(val, CORBA_long) = PyInt_AsLong(value);
	advanceptr(val, sizeof(CORBA_octet));
	if (!PyErr_Occurred()) ret = TRUE;
	break;
    case CORBA_tk_any:
	if (PyObject_TypeCheck(value, &PyCORBA_Any_Type)) {
	    alignval(val, ORBIT_ALIGNOF_CORBA_ANY);
	    CORBA_any__copy(&getval(val, CORBA_any),
			    &((PyCORBA_Any *)value)->any);
	    advanceptr(val, sizeof(CORBA_any));
	    ret = TRUE;
	}
	break;
    case CORBA_tk_TypeCode:
	alignval(val, ORBIT_ALIGNOF_CORBA_POINTER);
	if (PyObject_TypeCheck(value, &PyCORBA_TypeCode_Type)) {
	    getval(val, CORBA_TypeCode) =
		(CORBA_TypeCode)CORBA_Object_duplicate(
			(CORBA_Object)((PyCORBA_TypeCode *)value)->tc, NULL);
	    ret = TRUE;
	}
	advanceptr(val, sizeof(CORBA_TypeCode));
	break;
    case CORBA_tk_Principal:
	g_warning("can't marshal Principal");
	break;
    case CORBA_tk_objref:
	alignval(val, ORBIT_ALIGNOF_CORBA_POINTER);
	if (value == Py_None) {
	    getval(val, CORBA_Object) = CORBA_OBJECT_NIL;
	    ret = TRUE;
	} else if (PyObject_TypeCheck(value, &PyCORBA_Object_Type)) {
	    CORBA_Object objref = ((PyCORBA_Object *)value)->objref;
	    getval(val, CORBA_Object) = CORBA_Object_duplicate(objref, NULL);
	    advanceptr(val, sizeof(CORBA_Object));
	    ret = TRUE;
	}
	break;
    case CORBA_tk_except:
    case CORBA_tk_struct:
	alignval(val, tc->c_align);
	for (i = 0; i < tc->sub_parts; i++) {
	    gchar *pyname;
	    PyObject *item;
	    gboolean itemret;

	    pyname = _pyorbit_escape_name(tc->subnames[i]);
	    item = PyObject_GetAttrString(value, pyname);
	    g_free(pyname);
	    if (!item) break;
	    itemret = marshal_value(tc->subtypes[i], val, item);
	    Py_DECREF(item);
	    if (!itemret) break;
	}
	if (i == tc->sub_parts) ret = TRUE; /* no error */
	break;
    case CORBA_tk_union: {
	PyObject *discrim, *subval;
	CORBA_TypeCode subtc;
	gconstpointer body;
	int sz = 0;

	discrim = PyObject_GetAttrString(value, "_d");
	if (!discrim) break;
	subval = PyObject_GetAttrString(value, "_v");
	if (!subval) break;

	alignval(val, MAX(tc->c_align, tc->discriminator->c_align));
	ret = marshal_value(tc->discriminator, val, discrim);
	if (!ret) {
	    Py_DECREF(discrim);
	    Py_DECREF(subval);
	    break;
	}

	/* calculate allocation info */
	for (i = 0; i < tc->sub_parts; i++) {
	    sz = MAX(sz, ORBit_gather_alloc_info(tc->subtypes[i]));
	}
	subtc = get_union_tc(tc, discrim);
	Py_DECREF(discrim);
	if (!subtc) {
	    Py_DECREF(subval);
	    break;
	}

	alignval(val, tc->c_align);
	body = *val;

	ret = marshal_value(subtc, &body, subval);
	Py_DECREF(subval);
	advanceptr(val, sz);
	break;
    }
    case CORBA_tk_string:
	if (PyString_Check(value)) {
	    /* error out if python string is longer than the bound
	     * specified in the string typecode. */
	    if (tc->length > 0 && PyString_Size(value) > tc->length)
		break;

	    alignval(val, ORBIT_ALIGNOF_CORBA_POINTER);
	    getval(val, CORBA_string) = CORBA_string_dup(PyString_AsString(value));
	    advanceptr(val, sizeof(CORBA_char *));
	    ret = TRUE;
	}
	break;
    case CORBA_tk_sequence: 
	if (PySequence_Check(value)) {
	    CORBA_sequence_CORBA_octet *sval;
	    gconstpointer seqval;
	    gint i;

	    /* error out if python sequence is longer than the bound
	     * specified in the sequence typecode. */
	    if (tc->length > 0 && PySequence_Length(value) > tc->length)
		break;

	    alignval(val, ORBIT_ALIGNOF_CORBA_SEQ);
	    sval = (CORBA_sequence_CORBA_octet *)*val;
	    if (CORBA_TypeCode_equal(tc->subtypes[0], TC_CORBA_octet, NULL)
		&& PyString_Check(value))
	    {
		Py_ssize_t length;
		char *buffer;
		if (PyString_AsStringAndSize(value, &buffer, &length) == -1)
		    ret = FALSE;
		else {
		    sval->_release = CORBA_TRUE;
		    sval->_buffer  = ORBit_alloc_tcval(TC_CORBA_octet, length);
		    memcpy(sval->_buffer, buffer, length);
		    sval->_length  = length;
		    ret = TRUE;
		}
	    } else {
		sval->_release = TRUE;
		sval->_length = PySequence_Length(value);
		sval->_buffer = ORBit_alloc_tcval(tc->subtypes[0], sval->_length);
		seqval = sval->_buffer;
		for (i = 0; i < sval->_length; i++) {
		    PyObject *item = PySequence_GetItem(value, i);
		    gboolean itemret;
		    
		    if (!item) break;
		    itemret = marshal_value(tc->subtypes[0], &seqval, item);
		    Py_DECREF(item);
		    if (!itemret) break;
		}
		if (i == sval->_length) ret = TRUE; /* no error */
	    }
	    advanceptr(val, sizeof(CORBA_sequence_CORBA_octet));
	}
	break;
    case CORBA_tk_array:
	if (PySequence_Check(value) &&
	    PySequence_Length(value) == tc->length) {
	    gint i;

	    for (i = 0; i < tc->length; i++) {
		PyObject *item = PySequence_GetItem(value, i);
		gboolean itemret;

		if (!item) break;
		itemret = marshal_value(tc->subtypes[0], val, item);
		Py_DECREF(item);
		if (!itemret) break;
	    }
	    if (i == tc->length) ret = TRUE; /* no error */
	}
	break;
    case CORBA_tk_longlong:
	alignval(val, ORBIT_ALIGNOF_CORBA_LONG_LONG);
	if (PyLong_Check(value))
	    getval(val, CORBA_long_long) = PyLong_AsLongLong(value);
	else
	    getval(val, CORBA_long_long) = PyInt_AsLong(value);
	advanceptr(val, sizeof(CORBA_long_long));
	if (!PyErr_Occurred()) ret = TRUE;
	break;
    case CORBA_tk_ulonglong:
	alignval(val, ORBIT_ALIGNOF_CORBA_LONG_LONG);
	if (PyLong_Check(value))
	    getval(val, CORBA_unsigned_long_long) =PyLong_AsUnsignedLongLong(value);
	else
	    getval(val, CORBA_unsigned_long_long) = PyInt_AsLong(value);
	advanceptr(val, sizeof(CORBA_unsigned_long_long));
	if (!PyErr_Occurred()) ret = TRUE;
	break;
    case CORBA_tk_longdouble:
	g_warning("can't marshal long double");
	break;
    case CORBA_tk_wchar:
	if (PyUnicode_Check(value) && PyUnicode_GetSize(value) == 1) {
	    alignval(val, ORBIT_ALIGNOF_CORBA_SHORT);
	    getval(val, CORBA_wchar) = PyUnicode_AsUnicode(value)[0];
	    advanceptr(val, sizeof(CORBA_wchar));
	    ret = TRUE;
	}
	break;
    case CORBA_tk_wstring:
	if (PyUnicode_Check(value)) {
	    int length = PyUnicode_GetSize(value);
	    Py_UNICODE *unicode = PyUnicode_AsUnicode(value);
	    CORBA_wchar *wstr;

	    /* error out if python unicode string is longer than the
	     * bound specified in the wstring typecode. */
	    if (tc->length > 0 && length > tc->length)
		break;

	    alignval(val, ORBIT_ALIGNOF_CORBA_POINTER);
	    wstr = CORBA_wstring_alloc(length);
	    getval(val, CORBA_wstring) = wstr;
	    for (i = 0; i < length; i++) {
		wstr[i] = unicode[i];
	    }
	    advanceptr(val, sizeof(CORBA_wchar *));
	    ret = TRUE;
	}
	break;
    default:
	g_warning("unhandled typecode: %s (kind=%d)", tc->repo_id, tc->kind);
	break;
    }
    if (!ret)
	PyErr_Clear();
    return ret;
}