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

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Text;

namespace Python.Runtime
{
    /// 
    /// This file defines objects to support binary interop with the Python
    /// runtime. Generally, the definitions here need to be kept up to date
    /// when moving to new Python versions.
    /// 
    [Serializable]
    [AttributeUsage(AttributeTargets.All)]
    public class DocStringAttribute : Attribute
    {
        public DocStringAttribute(string docStr)
        {
            DocString = docStr;
        }

        public string DocString
        {
            get { return docStr; }
            set { docStr = value; }
        }

        private string docStr;
    }

    [Serializable]
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate)]
    internal class PythonMethodAttribute : Attribute
    {
        public PythonMethodAttribute()
        {
        }
    }

    [Serializable]
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate)]
    internal class ModuleFunctionAttribute : Attribute
    {
        public ModuleFunctionAttribute()
        {
        }
    }

    [Serializable]
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate)]
    internal class ForbidPythonThreadsAttribute : Attribute
    {
        public ForbidPythonThreadsAttribute()
        {
        }
    }


    [Serializable]
    [AttributeUsage(AttributeTargets.Property)]
    internal class ModulePropertyAttribute : Attribute
    {
        public ModulePropertyAttribute()
        {
        }
    }


    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    internal class ObjectOffset
    {
        static ObjectOffset()
        {
            int size = IntPtr.Size;
            var n = 0; // Py_TRACE_REFS add two pointers to PyObject_HEAD
#if PYTHON_WITH_PYDEBUG
            _ob_next = 0;
            _ob_prev = 1 * size;
            n = 2;
#endif
            ob_refcnt = (n + 0) * size;
            ob_type = (n + 1) * size;
            ob_dict = (n + 2) * size;
            ob_data = (n + 3) * size;
        }

        public static int magic(IntPtr ob)
        {
            if ((Runtime.PyObject_TypeCheck(ob, Exceptions.BaseException) ||
                 (Runtime.PyType_Check(ob) && Runtime.PyType_IsSubtype(ob, Exceptions.BaseException))))
            {
                return ExceptionOffset.ob_data;
            }
            return ob_data;
        }

        public static int DictOffset(IntPtr ob)
        {
            if ((Runtime.PyObject_TypeCheck(ob, Exceptions.BaseException) ||
                 (Runtime.PyType_Check(ob) && Runtime.PyType_IsSubtype(ob, Exceptions.BaseException))))
            {
                return ExceptionOffset.ob_dict;
            }
            return ob_dict;
        }

        public static int Size(IntPtr ob)
        {
            if ((Runtime.PyObject_TypeCheck(ob, Exceptions.BaseException) ||
                 (Runtime.PyType_Check(ob) && Runtime.PyType_IsSubtype(ob, Exceptions.BaseException))))
            {
                return ExceptionOffset.Size();
            }
#if PYTHON_WITH_PYDEBUG
            return 6 * IntPtr.Size;
#else
            return 4 * IntPtr.Size;
#endif
        }

#if PYTHON_WITH_PYDEBUG
        public static int _ob_next;
        public static int _ob_prev;
#endif
        public static int ob_refcnt;
        public static int ob_type;
        private static int ob_dict;
        private static int ob_data;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    internal class ExceptionOffset
    {
        static ExceptionOffset()
        {
            Type type = typeof(ExceptionOffset);
            FieldInfo[] fi = type.GetFields();
            int size = IntPtr.Size;
            for (int i = 0; i < fi.Length; i++)
            {
                fi[i].SetValue(null, (i * size) + ObjectOffset.ob_type + size);
            }
        }

        public static int Size()
        {
            return ob_data + IntPtr.Size;
        }

        // PyException_HEAD
        // (start after PyObject_HEAD)
        public static int dict = 0;
        public static int args = 0;
#if PYTHON2
        public static int message = 0;
#elif PYTHON3
        public static int traceback = 0;
        public static int context = 0;
        public static int cause = 0;
        public static int suppress_context = 0;
#endif

        // extra c# data
        public static int ob_dict;
        public static int ob_data;
    }


#if PYTHON3
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    internal class BytesOffset
    {
        static BytesOffset()
        {
            Type type = typeof(BytesOffset);
            FieldInfo[] fi = type.GetFields();
            int size = IntPtr.Size;
            for (int i = 0; i < fi.Length; i++)
            {
                fi[i].SetValue(null, i * size);
            }
        }

        /* The *real* layout of a type object when allocated on the heap */
        //typedef struct _heaptypeobject {
#if PYTHON_WITH_PYDEBUG
/* _PyObject_HEAD_EXTRA defines pointers to support a doubly-linked list of all live heap objects. */
        public static int _ob_next = 0;
        public static int _ob_prev = 0;
#endif
        // PyObject_VAR_HEAD {
        //     PyObject_HEAD {
        public static int ob_refcnt = 0;
        public static int ob_type = 0;
        // }
        public static int ob_size = 0; /* Number of items in _VAR_iable part */
        // }
        public static int ob_shash = 0;
        public static int ob_sval = 0; /* start of data */

        /* Invariants:
         *     ob_sval contains space for 'ob_size+1' elements.
         *     ob_sval[ob_size] == 0.
         *     ob_shash is the hash of the string or -1 if not computed yet.
         */
        //} PyBytesObject;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    internal class ModuleDefOffset
    {
        static ModuleDefOffset()
        {
            Type type = typeof(ModuleDefOffset);
            FieldInfo[] fi = type.GetFields();
            int size = IntPtr.Size;
            for (int i = 0; i < fi.Length; i++)
            {
                fi[i].SetValue(null, (i * size) + TypeOffset.ob_size);
            }
        }

        public static IntPtr AllocModuleDef(string modulename)
        {
            byte[] ascii = Encoding.ASCII.GetBytes(modulename);
            int size = name + ascii.Length + 1;
            IntPtr ptr = Marshal.AllocHGlobal(size);
            for (int i = 0; i < m_free; i += IntPtr.Size)
                Marshal.WriteIntPtr(ptr, i, IntPtr.Zero);
            Marshal.Copy(ascii, 0, (IntPtr)(ptr + name), ascii.Length);
            Marshal.WriteIntPtr(ptr, m_name, (IntPtr)(ptr + name));
            Marshal.WriteByte(ptr, name + ascii.Length, 0);
            return ptr;
        }

        public static void FreeModuleDef(IntPtr ptr)
        {
            Marshal.FreeHGlobal(ptr);
        }

        // typedef struct PyModuleDef{
        //  typedef struct PyModuleDef_Base {
        // starts after PyObject_HEAD (TypeOffset.ob_type + 1)
        public static int m_init = 0;
        public static int m_index = 0;
        public static int m_copy = 0;
        //  } PyModuleDef_Base
        public static int m_name = 0;
        public static int m_doc = 0;
        public static int m_size = 0;
        public static int m_methods = 0;
        public static int m_reload = 0;
        public static int m_traverse = 0;
        public static int m_clear = 0;
        public static int m_free = 0;
        // } PyModuleDef

        public static int name = 0;
    }
#endif // PYTHON3

    /// 
    /// TypeFlags(): The actual bit values for the Type Flags stored
    /// in a class.
    /// Note that the two values reserved for stackless have been put
    /// to good use as PythonNet specific flags (Managed and Subclass)
    /// 
    internal class TypeFlags
    {
#if PYTHON2 // these flags were removed in Python 3
        public static int HaveGetCharBuffer = (1 

Web Proxy Viewer  |  New URL  |  Original Page