CORBA_wchar *
CORBA_wstring_dup (const CORBA_wchar *str)
{
	CORBA_wchar *retval;
	CORBA_unsigned_long len;

	if (!str)
		return NULL;

	len = CORBA_wstring_len (str);

	retval = CORBA_wstring_alloc (len);
	memcpy (retval, str, (len + 1) * 2);

	return retval;
}
Example #2
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;
}