25 PyObject* pp_get( PropertyProxy* pyprop, ObjectProxy* pyobj, PyObject* )
28 void* address = pyprop->GetAddress( pyobj );
29 if ( ! address || (ptrdiff_t)address == -1 )
34 if ( pyprop->fProperty & kIsArrayType )
38 if ( ! ptr || (ptrdiff_t)ptr == -1 ) {
40 return (PyObject*)pyprop;
43 if ( pyprop->fConverter != 0 ) {
44 PyObject* result = pyprop->fConverter->FromMemory( ptr );
52 if ( pyobj && ObjectProxy_Check( result ) ) {
53 if ( PyObject_SetAttr( result, PyStrings::gLifeLine, (PyObject*)pyobj ) == -1 )
59 PyErr_Format( PyExc_NotImplementedError,
60 "no converter available for \"%s\"", pyprop->GetName().c_str() );
67 int pp_set( PropertyProxy* pyprop, ObjectProxy* pyobj, PyObject* value )
69 const int errret = -1;
72 if ( ( pyprop->fProperty & kIsConstData ) ) {
73 PyErr_SetString( PyExc_TypeError,
"assignment to const data not allowed" );
77 ptrdiff_t address = (ptrdiff_t)pyprop->GetAddress( pyobj );
78 if ( ! address || address == -1 )
82 void* ptr = (
void*)address;
83 if ( pyprop->fProperty & kIsArrayType )
87 if ( pyprop->fConverter && pyprop->fConverter->ToMemory( value, ptr ) )
91 if ( ! PyErr_Occurred() )
92 PyErr_SetString( PyExc_RuntimeError,
"property type mismatch or assignment not allowed" );
99 PropertyProxy* pp_new( PyTypeObject* pytype, PyObject*, PyObject* )
102 PropertyProxy* pyprop = (PropertyProxy*)pytype->tp_alloc( pytype, 0 );
105 pyprop->fProperty = 0;
106 pyprop->fConverter = 0;
107 pyprop->fEnclosingScope = 0;
108 new ( &pyprop->fName ) std::string();
116 void pp_dealloc( PropertyProxy* pyprop )
119 delete pyprop->fConverter;
120 pyprop->fName.~string();
122 Py_TYPE(pyprop)->tp_free( (PyObject*)pyprop );
130 PyTypeObject PropertyProxy_Type = {
131 PyVarObject_HEAD_INIT( &PyType_Type, 0 )
132 (
char*)
"ROOT.PropertyProxy",
133 sizeof(PropertyProxy),
135 (destructor)pp_dealloc,
151 (
char*)
"PyROOT property proxy (internal)",
163 (descrgetfunc)pp_get,
164 (descrsetfunc)pp_set,
176 #
if PY_VERSION_HEX >= 0x02030000
179 #
if PY_VERSION_HEX >= 0x02060000
182 #
if PY_VERSION_HEX >= 0x03040000
191 void PyROOT::PropertyProxy::Set( Cppyy::TCppScope_t scope, Cppyy::TCppIndex_t idata )
193 fEnclosingScope = scope;
194 fName = Cppyy::GetDatamemberName( scope, idata );
195 fOffset = Cppyy::GetDatamemberOffset( scope, idata );
196 fProperty = Cppyy::IsStaticData( scope, idata ) ? kIsStaticData : 0;
198 Int_t size = Cppyy::GetDimensionSize( scope, idata, 0 );
200 fProperty |= kIsArrayType;
202 std::string fullType = Cppyy::GetDatamemberType( scope, idata );
203 if ( Cppyy::IsEnumData( scope, idata ) ) {
205 fullType = Cppyy::ResolveEnum(fullType);
206 fProperty |= kIsEnumData;
209 if ( Cppyy::IsConstData( scope, idata ) )
210 fProperty |= kIsConstData;
212 fConverter = CreateConverter( fullType, size );
217 void PyROOT::PropertyProxy::Set( Cppyy::TCppScope_t scope,
const std::string& name,
void* address, TEnum* en )
219 std::string cppType = Cppyy::ResolveEnum(en);
221 fEnclosingScope = scope;
223 fOffset = (ptrdiff_t)address;
224 fProperty = (kIsStaticData | kIsConstData | kIsEnumData );
225 fConverter = CreateConverter( cppType, -1 );
231 void* PyROOT::PropertyProxy::GetAddress( ObjectProxy* pyobj ) {
232 if ( fProperty & kIsStaticData )
233 return (
void*)fOffset;
240 if ( ! ObjectProxy_Check( pyobj ) ) {
241 PyErr_Format( PyExc_TypeError,
242 "object instance required for access to property \"%s\"", GetName().c_str() );
246 void* obj = pyobj->GetObject();
248 PyErr_SetString( PyExc_ReferenceError,
"attempt to access a null-pointer" );
253 ptrdiff_t offset = 0;
254 if ( pyobj->ObjectIsA() != fEnclosingScope)
255 offset = Cppyy::GetBaseOffset( pyobj->ObjectIsA(), fEnclosingScope, obj, 1 );
257 return (
void*)((ptrdiff_t)obj + offset + fOffset);