2008-01-13 18:44:42 +03:00
/*
Unix SMB / CIFS implementation .
Python / Talloc glue
Copyright ( C ) Jelmer Vernooij < jelmer @ samba . org > 2008
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2010-01-20 05:07:09 +03:00
# include <Python.h>
2009-01-30 21:38:09 +03:00
# include "replace.h"
2008-10-24 04:52:51 +04:00
# include <talloc.h>
2010-03-29 01:35:30 +04:00
# include "pytalloc.h"
2010-10-24 21:52:01 +04:00
# include <assert.h>
2016-02-22 04:02:28 +03:00
# include "pytalloc_private.h"
2008-01-13 18:44:42 +03:00
2011-08-10 17:15:18 +04:00
_PUBLIC_ PyTypeObject * pytalloc_GetObjectType ( void )
2010-12-01 00:59:51 +03:00
{
static PyTypeObject * type = NULL ;
PyObject * mod ;
if ( type ! = NULL ) {
return type ;
}
mod = PyImport_ImportModule ( " talloc " ) ;
if ( mod = = NULL ) {
return NULL ;
}
type = ( PyTypeObject * ) PyObject_GetAttrString ( mod , " Object " ) ;
Py_DECREF ( mod ) ;
return type ;
}
2016-02-22 04:02:28 +03:00
_PUBLIC_ PyTypeObject * pytalloc_GetBaseObjectType ( void )
{
static PyTypeObject * type = NULL ;
PyObject * mod ;
if ( type ! = NULL ) {
return type ;
}
mod = PyImport_ImportModule ( " talloc " ) ;
if ( mod = = NULL ) {
return NULL ;
}
type = ( PyTypeObject * ) PyObject_GetAttrString ( mod , " BaseObject " ) ;
Py_DECREF ( mod ) ;
return type ;
}
2008-12-23 06:06:21 +03:00
/**
* Import an existing talloc pointer into a Python object .
*/
2011-08-10 17:15:18 +04:00
_PUBLIC_ PyObject * pytalloc_steal_ex ( PyTypeObject * py_type , TALLOC_CTX * mem_ctx ,
2016-02-22 04:02:28 +03:00
void * ptr )
2008-01-13 18:44:42 +03:00
{
2016-02-22 04:02:28 +03:00
PyTypeObject * BaseObjectType = pytalloc_GetBaseObjectType ( ) ;
PyTypeObject * ObjectType = pytalloc_GetObjectType ( ) ;
if ( mem_ctx = = NULL ) {
return PyErr_NoMemory ( ) ;
2008-05-23 17:09:51 +04:00
}
2016-02-22 04:02:28 +03:00
if ( PyType_IsSubtype ( py_type , BaseObjectType ) ) {
pytalloc_BaseObject * ret
= ( pytalloc_BaseObject * ) py_type - > tp_alloc ( py_type , 0 ) ;
ret - > talloc_ctx = talloc_new ( NULL ) ;
if ( ret - > talloc_ctx = = NULL ) {
return NULL ;
}
/*
* This allows us to keep multiple references to this object -
* we only reference this context , which is per ptr , not the
* talloc_ctx , which is per pytalloc_Object
*/
if ( talloc_steal ( ret - > talloc_ctx , mem_ctx ) = = NULL ) {
return NULL ;
}
ret - > talloc_ptr_ctx = mem_ctx ;
talloc_set_name_const ( ret - > talloc_ctx , py_type - > tp_name ) ;
ret - > ptr = ptr ;
return ( PyObject * ) ret ;
} else if ( PyType_IsSubtype ( py_type , ObjectType ) ) {
pytalloc_Object * ret
= ( pytalloc_Object * ) py_type - > tp_alloc ( py_type , 0 ) ;
ret - > talloc_ctx = talloc_new ( NULL ) ;
if ( ret - > talloc_ctx = = NULL ) {
return NULL ;
}
if ( talloc_steal ( ret - > talloc_ctx , mem_ctx ) = = NULL ) {
return NULL ;
}
talloc_set_name_const ( ret - > talloc_ctx , py_type - > tp_name ) ;
ret - > ptr = ptr ;
return ( PyObject * ) ret ;
} else {
PyErr_SetString ( PyExc_RuntimeError ,
" pytalloc_steal_ex() called for object type "
" not based on talloc " ) ;
2009-07-01 08:05:17 +04:00
return NULL ;
}
}
2010-08-25 08:29:59 +04:00
/**
* Import an existing talloc pointer into a Python object .
*/
2011-08-10 17:15:18 +04:00
_PUBLIC_ PyObject * pytalloc_steal ( PyTypeObject * py_type , void * ptr )
2010-08-25 08:29:59 +04:00
{
2011-08-10 17:15:18 +04:00
return pytalloc_steal_ex ( py_type , ptr , ptr ) ;
2010-08-25 08:29:59 +04:00
}
2009-07-01 08:05:17 +04:00
/**
* Import an existing talloc pointer into a Python object , leaving the
* original parent , and creating a reference to the object in the python
2016-02-22 04:02:28 +03:00
* object .
*
* We remember the object we hold the reference to ( a
* possibly - non - talloc pointer ) , the existing parent ( typically the
* start of the array ) and the new referenced parent . That way we can
* cope with the fact that we will have multiple parents , one per time
* python sees the object .
2009-07-01 08:05:17 +04:00
*/
2016-02-22 04:02:28 +03:00
_PUBLIC_ PyObject * pytalloc_reference_ex ( PyTypeObject * py_type ,
TALLOC_CTX * mem_ctx , void * ptr )
2009-07-01 08:05:17 +04:00
{
2016-02-22 04:02:28 +03:00
PyTypeObject * BaseObjectType = pytalloc_GetBaseObjectType ( ) ;
PyTypeObject * ObjectType = pytalloc_GetObjectType ( ) ;
2010-08-28 15:53:27 +04:00
2016-02-22 04:02:28 +03:00
if ( mem_ctx = = NULL ) {
return PyErr_NoMemory ( ) ;
2010-08-28 15:53:27 +04:00
}
2016-02-22 04:02:28 +03:00
if ( PyType_IsSubtype ( py_type , BaseObjectType ) ) {
pytalloc_BaseObject * ret
= ( pytalloc_BaseObject * ) py_type - > tp_alloc ( py_type , 0 ) ;
ret - > talloc_ctx = talloc_new ( NULL ) ;
if ( ret - > talloc_ctx = = NULL ) {
return NULL ;
}
if ( talloc_reference ( ret - > talloc_ctx , mem_ctx ) = = NULL ) {
return NULL ;
}
talloc_set_name_const ( ret - > talloc_ctx , py_type - > tp_name ) ;
ret - > talloc_ptr_ctx = mem_ctx ;
ret - > ptr = ptr ;
return ( PyObject * ) ret ;
} else if ( PyType_IsSubtype ( py_type , ObjectType ) ) {
pytalloc_Object * ret
= ( pytalloc_Object * ) py_type - > tp_alloc ( py_type , 0 ) ;
ret - > talloc_ctx = talloc_new ( NULL ) ;
if ( ret - > talloc_ctx = = NULL ) {
return NULL ;
}
if ( talloc_reference ( ret - > talloc_ctx , mem_ctx ) = = NULL ) {
return NULL ;
}
talloc_set_name_const ( ret - > talloc_ctx , py_type - > tp_name ) ;
ret - > ptr = ptr ;
return ( PyObject * ) ret ;
} else {
PyErr_SetString ( PyExc_RuntimeError ,
" pytalloc_reference_ex() called for object type "
" not based on talloc " ) ;
2008-05-23 17:09:51 +04:00
return NULL ;
}
2008-01-13 18:44:42 +03:00
}
2008-01-13 20:38:12 +03:00
2015-01-15 16:07:09 +03:00
# if PY_MAJOR_VERSION < 3
2009-09-28 17:03:17 +04:00
static void py_cobject_talloc_free ( void * ptr )
{
talloc_free ( ptr ) ;
}
2011-08-10 17:15:18 +04:00
_PUBLIC_ PyObject * pytalloc_CObject_FromTallocPtr ( void * ptr )
2009-09-28 17:03:17 +04:00
{
2010-08-28 16:00:21 +04:00
if ( ptr = = NULL ) {
Py_RETURN_NONE ;
}
2009-09-28 17:03:17 +04:00
return PyCObject_FromVoidPtr ( ptr , py_cobject_talloc_free ) ;
}
2010-08-28 16:00:21 +04:00
2015-01-15 16:07:09 +03:00
# endif
2011-08-10 17:15:18 +04:00
_PUBLIC_ int pytalloc_Check ( PyObject * obj )
2010-12-01 00:59:51 +03:00
{
2011-08-10 17:15:18 +04:00
PyTypeObject * tp = pytalloc_GetObjectType ( ) ;
2010-12-01 00:59:51 +03:00
return PyObject_TypeCheck ( obj , tp ) ;
}
2016-02-22 04:29:15 +03:00
2016-02-22 04:02:28 +03:00
_PUBLIC_ int pytalloc_BaseObject_check ( PyObject * obj )
{
PyTypeObject * tp = pytalloc_GetBaseObjectType ( ) ;
return PyObject_TypeCheck ( obj , tp ) ;
}
_PUBLIC_ size_t pytalloc_BaseObject_size ( void )
{
return sizeof ( pytalloc_BaseObject ) ;
}
2016-02-22 10:47:07 +03:00
_PUBLIC_ void * _pytalloc_get_type ( PyObject * py_obj , const char * type_name )
{
void * ptr = _pytalloc_get_ptr ( py_obj ) ;
void * type_obj = talloc_check_name ( ptr , type_name ) ;
if ( type_obj = = NULL ) {
const char * name = talloc_get_name ( ptr ) ;
PyErr_Format ( PyExc_TypeError , " pytalloc: expected %s, got %s " ,
type_name , name ) ;
return NULL ;
}
return ptr ;
}
2016-02-22 04:29:15 +03:00
_PUBLIC_ void * _pytalloc_get_ptr ( PyObject * py_obj )
{
2016-02-22 04:02:28 +03:00
if ( pytalloc_BaseObject_check ( py_obj ) ) {
return ( ( pytalloc_BaseObject * ) py_obj ) - > ptr ;
}
if ( pytalloc_Check ( py_obj ) ) {
return ( ( pytalloc_Object * ) py_obj ) - > ptr ;
}
return NULL ;
2016-02-22 04:29:15 +03:00
}
_PUBLIC_ TALLOC_CTX * _pytalloc_get_mem_ctx ( PyObject * py_obj )
{
2016-02-22 04:02:28 +03:00
if ( pytalloc_BaseObject_check ( py_obj ) ) {
return ( ( pytalloc_BaseObject * ) py_obj ) - > talloc_ptr_ctx ;
}
if ( pytalloc_Check ( py_obj ) ) {
return ( ( pytalloc_Object * ) py_obj ) - > talloc_ctx ;
}
return NULL ;
2016-02-22 04:29:15 +03:00
}