[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/pythonindy/pythonnet/master/pythonnet/src/runtime/fieldobject.cs [Back]  [Original]

// ==========================================================================
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.
// ==========================================================================

using System;
using System.Collections;
using System.Reflection;

namespace Python.Runtime {

    //========================================================================
    // Implements a Python descriptor type that provides access to CLR fields.
    //========================================================================

    internal class FieldObject : ExtensionType {

	FieldInfo info;

	public FieldObject(FieldInfo info) : base() {
	    this.info = info;
	}

	//====================================================================
	// Descriptor __get__ implementation. This method returns the 
	// value of the field on the given object. The returned value
	// is converted to an appropriately typed Python object.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) {
	    FieldObject self = (FieldObject)GetManagedObject(ds);
	    Object result;

	    if (self == null) {
		return IntPtr.Zero;
	    }

	    FieldInfo info = self.info;

	    if ((ob == IntPtr.Zero) || (ob == Runtime.PyNone)) {
		if (!info.IsStatic) {
		    Exceptions.SetError(Exceptions.TypeError, 
			       "instance attribute must be accessed " + 
			       "through a class instance"
			       );
		    return IntPtr.Zero;
		}
		try {
		    result = info.GetValue(null);
		    return Converter.ToPython(result, info.FieldType);
		}
		catch(Exception e) {
		    Exceptions.SetError(Exceptions.TypeError, e.Message);
		    return IntPtr.Zero;
		}
	    }

	    try {
	        CLRObject co = (CLRObject)GetManagedObject(ob);
		result = info.GetValue(co.inst);
		return Converter.ToPython(result, info.FieldType);
	    }
	    catch(Exception e) {
		Exceptions.SetError(Exceptions.TypeError, e.Message);
		return IntPtr.Zero;
	    }
	}

	//====================================================================
	// Descriptor __set__ implementation. This method sets the value of
	// a field based on the given Python value. The Python value must be
	// convertible to the type of the field.
	//====================================================================

	[CallConvCdecl()]
	public static new int tp_descr_set(IntPtr ds, IntPtr ob, IntPtr val) {
	    FieldObject self = (FieldObject)GetManagedObject(ds);
	    Object newval;

	    if (self == null) {
		return -1;
	    }

	    if (val == IntPtr.Zero) {
		Exceptions.SetError(Exceptions.TypeError, 
			            "cannot delete field"
				    );
		return -1;
	    }

	    FieldInfo info = self.info;

	    if (info.IsLiteral || info.IsInitOnly) {
		Exceptions.SetError(Exceptions.TypeError, 
				    "field is read-only"
				    );
		return -1;
	    }

	    bool is_static = info.IsStatic;

	    if ((ob == IntPtr.Zero) || (ob == Runtime.PyNone)) {
		if (!is_static) {
		    Exceptions.SetError(Exceptions.TypeError, 
			       "instance attribute must be set " + 
			       "through a class instance"
			       );
		    return -1;
		}
	    }

	    if (!Converter.ToManaged(val, info.FieldType, out newval, 
				      true)) {
		return -1;
	    }

	    try {
		if (!is_static) {
		    CLRObject co = (CLRObject)GetManagedObject(ob);
		    info.SetValue(co.inst, newval);
		}
		else {
		    info.SetValue(null, newval);
		}
		return 0;
	    }
	    catch(Exception e) {
		Exceptions.SetError(Exceptions.TypeError, e.Message);
		return -1;
	    }
	}

	//====================================================================
	// Descriptor __repr__ implementation.
	//====================================================================

	[CallConvCdecl()]
	public static IntPtr tp_repr(IntPtr ob) {
	    FieldObject self = (FieldObject)GetManagedObject(ob);
	    string s = String.Format("", self.info.Name);
	    return Runtime.PyString_FromStringAndSize(s, s.Length);
	}

    }


}

Web Proxy Viewer  |  New URL  |  Original Page