Example #1
0
        internal IntPtr tpHandle;   // PyType *


        //====================================================================
        // Given a Python object, return the associated managed object or null.
        //====================================================================

        internal static ManagedType GetManagedObject(IntPtr ob)
        {
            if (ob != IntPtr.Zero)
            {
                IntPtr tp = Runtime.PyObject_TYPE(ob);
                if (tp == Runtime.PyTypeType || tp == Runtime.PyCLRMetaType)
                {
                    tp = ob;
                }

                int flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
                if ((flags & TypeFlags.Managed) != 0)
                {
                    IntPtr op = (tp == ob) ?
                                Marshal.ReadIntPtr(tp, TypeOffset.magic()) :
                                Marshal.ReadIntPtr(ob, ObjectOffset.magic());
                    GCHandle gc = (GCHandle)op;
                    return((ManagedType)gc.Target);
                }

                // In certain situations, we need to recognize a wrapped
                // exception class and be willing to unwrap the class :(

                if (Runtime.wrap_exceptions)
                {
                    IntPtr e = Exceptions.UnwrapExceptionClass(ob);
                    if ((e != IntPtr.Zero) && (e != ob))
                    {
                        ManagedType m = GetManagedObject(e);
                        Runtime.Decref(e);
                        return(m);
                    }
                }
            }
            return(null);
        }
Example #2
0
        internal static bool ToManagedValue(IntPtr value, Type obType,
                                            out Object result, bool setError)
        {
            // Common case: if the Python value is a wrapped managed object
            // instance, just return the wrapped object.
            ManagedType mt = ManagedType.GetManagedObject(value);

            result = null;

            // XXX - hack to support objects wrapped in old-style classes
            // (such as exception objects).
            if (Runtime.wrap_exceptions)
            {
                if (mt == null)
                {
                    if (Runtime.PyObject_IsInstance(
                            value, Exceptions.Exception
                            ) > 0)
                    {
                        IntPtr p = Runtime.PyObject_GetAttrString(value, "_inner");
                        if (p != IntPtr.Zero)
                        {
                            // This is safe because we know that the __dict__ of
                            // value holds a reference to _inner.
                            value = p;
                            Runtime.Decref(p);
                            mt = ManagedType.GetManagedObject(value);
                        }
                    }
                    IntPtr c = Exceptions.UnwrapExceptionClass(value);
                    if ((c != IntPtr.Zero) && (c != value))
                    {
                        value = c;
                        Runtime.Decref(c);
                        mt = ManagedType.GetManagedObject(value);
                    }
                }
            }

            if (mt != null)
            {
                if (mt is CLRObject)
                {
                    object tmp = ((CLRObject)mt).inst;
                    if (obType.IsInstanceOfType(tmp))
                    {
                        result = tmp;
                        return(true);
                    }
                    string err = "value cannot be converted to {0}";
                    err = String.Format(err, obType);
                    Exceptions.SetError(Exceptions.TypeError, err);
                    return(false);
                }
                if (mt is ClassBase)
                {
                    result = ((ClassBase)mt).type;
                    return(true);
                }
                // shouldnt happen
                return(false);
            }

            if (value == Runtime.PyNone && !obType.IsValueType)
            {
                result = null;
                return(true);
            }

            if (obType.IsArray)
            {
                return(ToArray(value, obType, out result, setError));
            }

            if (obType.IsEnum)
            {
                return(ToEnum(value, obType, out result, setError));
            }

            // Conversion to 'Object' is done based on some reasonable
            // default conversions (Python string -> managed string,
            // Python int -> Int32 etc.).

            if (obType == objectType)
            {
                if (Runtime.IsStringType(value))
                {
                    return(ToPrimitive(value, stringType, out result,
                                       setError));
                }

                else if (Runtime.PyBool_Check(value))
                {
                    return(ToPrimitive(value, boolType, out result, setError));
                }

                else if (Runtime.PyInt_Check(value))
                {
                    return(ToPrimitive(value, int32Type, out result, setError));
                }

                else if (Runtime.PyLong_Check(value))
                {
                    return(ToPrimitive(value, int64Type, out result, setError));
                }

                else if (Runtime.PyFloat_Check(value))
                {
                    return(ToPrimitive(value, doubleType, out result, setError));
                }

                else if (Runtime.PySequence_Check(value))
                {
                    return(ToArray(value, typeof(object[]), out result,
                                   setError));
                }

                if (setError)
                {
                    Exceptions.SetError(Exceptions.TypeError,
                                        "value cannot be converted to Object"
                                        );
                }

                return(false);
            }

            // Conversion to 'Type' is done using the same mappings as above
            // for objects.

            if (obType == typeType)
            {
                if (value == Runtime.PyStringType)
                {
                    result = stringType;
                    return(true);
                }

                else if (value == Runtime.PyBoolType)
                {
                    result = boolType;
                    return(true);
                }

                else if (value == Runtime.PyIntType)
                {
                    result = int32Type;
                    return(true);
                }

                else if (value == Runtime.PyLongType)
                {
                    result = int64Type;
                    return(true);
                }

                else if (value == Runtime.PyFloatType)
                {
                    result = doubleType;
                    return(true);
                }

                else if (value == Runtime.PyListType || value == Runtime.PyTupleType)
                {
                    result = typeof(object[]);
                    return(true);
                }

                if (setError)
                {
                    Exceptions.SetError(Exceptions.TypeError,
                                        "value cannot be converted to Type"
                                        );
                }

                return(false);
            }

            return(ToPrimitive(value, obType, out result, setError));
        }