mirror of
https://github.com/php/php-src.git
synced 2024-11-26 03:16:33 +08:00
220 lines
7.2 KiB
C
220 lines
7.2 KiB
C
/*
|
|
+----------------------------------------------------------------------+
|
|
| PHP version 4.0 |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 1997-2001 The PHP Group |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 2.02 of the PHP license, |
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
| available at through the world-wide-web at |
|
|
| http://www.php.net/license/2_02.txt. |
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
| Author: David Eriksson <david@2good.com> |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
/*
|
|
* $Id$
|
|
* vim: syntax=c tabstop=2 shiftwidth=2
|
|
*/
|
|
|
|
/* -----------------------------------------------------------------------
|
|
*
|
|
* Macros and things to simplify making PHP classes
|
|
*
|
|
* -----------------------------------------------------------------------
|
|
*/
|
|
#ifndef __orbit_class_h__
|
|
#define __orbit_class_h__
|
|
|
|
#include <zend.h>
|
|
#include <zend_API.h>
|
|
|
|
#define CONSTRUCTOR 1
|
|
#define DESTRUCTOR 2
|
|
#define CALL_FUNCTION 4
|
|
#define PUT_PROPERTY 8
|
|
#define GET_PROPERTY 16
|
|
#define NO_FUNCTIONS (CONSTRUCTOR|DESTRUCTOR|PUT_PROPERTY|GET_PROPERTY)
|
|
#define NO_PROPERTIES (CONSTRUCTOR|DESTRUCTOR|CALL_FUNCTION)
|
|
|
|
/*
|
|
* sorry everyone but the constructor itself has to allocate the data
|
|
* structure for member variables!
|
|
*
|
|
* it also has to deallocate this in the destructor...
|
|
*/
|
|
typedef zend_bool (*Class_Constructor)
|
|
(void ** ppObject, int parameterCount, zval ** ppParameters);
|
|
typedef zend_bool (*Class_Destructor)
|
|
(void * pObject);
|
|
typedef zend_bool (*Class_CallFunction)
|
|
(void * pObject, const char * pFunctionName, int parameterCount, zval ** ppParameters, zval * pReturnValue);
|
|
typedef zend_bool (*Class_PutProperty)
|
|
(void * pObject, const char * pPropertyName, const zval * pValue);
|
|
typedef zend_bool (*Class_GetProperty)
|
|
(void * pObject, const char * pPropertyName, zval * pReturnValue);
|
|
|
|
/* put/get data connected to php object */
|
|
void orbit_save_data(zval * pPhpObject, int type, void * pData);
|
|
void * orbit_retrieve_data(const zval * pPhpObject, int type);
|
|
|
|
void orbit_class_function_call(
|
|
zend_class_entry * pClass,
|
|
int dataType,
|
|
zend_property_reference *pPropertyReference,
|
|
Class_Constructor pConstructor,
|
|
Class_CallFunction pCallFunction,
|
|
INTERNAL_FUNCTION_PARAMETERS);
|
|
|
|
/*
|
|
* use this macro in the header file
|
|
*/
|
|
#define DECLARE_CLASS(name) \
|
|
typedef struct _##name name##; \
|
|
zend_bool name##_Init(int module_number); \
|
|
void name##_SaveData(zval * pPhpObject, ##name * pData);\
|
|
##name * name##_RetrieveData(const zval * pPhpObject);\
|
|
zend_bool name##_PutProperty(##name * pObject, const char * pPropertyName, const zval * pValue);\
|
|
zend_bool name##_GetProperty(##name * pObject, const char * pPropertyName, zval * pReturnValue);\
|
|
/* end small macro */
|
|
|
|
/*
|
|
* Wrapper for a function call
|
|
*/
|
|
#define IMPLEMENT_FUNCTION_CALL(name, flags)\
|
|
static void _##name##_FunctionCall(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference * pPropertyReference) \
|
|
{ \
|
|
orbit_class_function_call( \
|
|
&name##_class_entry, \
|
|
name##_data_type, \
|
|
pPropertyReference, \
|
|
((flags) & CONSTRUCTOR) ? (Class_Constructor)name##_Constructor : NULL, \
|
|
((flags) & CALL_FUNCTION) ? (Class_CallFunction)name##_CallFunction : NULL, \
|
|
INTERNAL_FUNCTION_PARAM_PASSTHRU\
|
|
);\
|
|
}
|
|
|
|
/*
|
|
* wrapper for PutProperty
|
|
*/
|
|
#define IMPLEMENT_PUT_PROPERTY(name, flags)\
|
|
static int _##name##_PutProperty(zend_property_reference * pPropertyReference, zval * pValue)\
|
|
{\
|
|
int result = 0;\
|
|
if ((flags) & PUT_PROPERTY)\
|
|
{\
|
|
##name * p_data = (##name *)orbit_retrieve_data(pPropertyReference->object, name##_data_type);\
|
|
/* get variable name element */\
|
|
zend_overloaded_element * p_attribute_element = \
|
|
(zend_overloaded_element *)pPropertyReference->elements_list->tail->data;\
|
|
/* get variable name */\
|
|
char * p_attribute_name = p_attribute_element->element.value.str.val;\
|
|
if (p_data)\
|
|
result = ##name##_PutProperty(p_data, p_attribute_name, pValue) ? SUCCESS : FAILURE;\
|
|
else\
|
|
result = FAILURE;\
|
|
}\
|
|
else\
|
|
{\
|
|
zend_error(E_WARNING, "(Satellite) Can't set members in class");\
|
|
}\
|
|
return result;\
|
|
}
|
|
|
|
/*
|
|
* wrapper for GetProperty
|
|
*/
|
|
#define IMPLEMENT_GET_PROPERTY(name, flags)\
|
|
static zval _##name##_GetProperty(zend_property_reference * pPropertyReference)\
|
|
{\
|
|
zval value;\
|
|
ZVAL_NULL(&value);\
|
|
if ((flags) & GET_PROPERTY)\
|
|
{\
|
|
##name * p_data = (##name *)orbit_retrieve_data(pPropertyReference->object, name##_data_type);\
|
|
/* get variable name element */\
|
|
zend_overloaded_element * p_attribute_element = \
|
|
(zend_overloaded_element *)pPropertyReference->elements_list->tail->data;\
|
|
/* get variable name */\
|
|
char * p_attribute_name = p_attribute_element->element.value.str.val;\
|
|
if (p_data)\
|
|
##name##_GetProperty(p_data, p_attribute_name, &value);\
|
|
}\
|
|
else\
|
|
{\
|
|
zend_error(E_WARNING, "(Satellite) Can't get members in class");\
|
|
}\
|
|
return value;\
|
|
}
|
|
|
|
|
|
#define IMPLEMENT_INIT_EX(name, flags, functions, functioncall, getproperty, putproperty)\
|
|
zend_bool name##_Init(int module_number) \
|
|
{ \
|
|
/* register data type */ \
|
|
name##_data_type = register_list_destructors(name##_Destructor, NULL); \
|
|
\
|
|
/* register class */ \
|
|
INIT_OVERLOADED_CLASS_ENTRY( \
|
|
name##_class_entry, \
|
|
#name, \
|
|
functions, \
|
|
functioncall, \
|
|
getproperty, \
|
|
putproperty \
|
|
); \
|
|
\
|
|
zend_register_internal_class(&name##_class_entry TSRMLS_CC);\
|
|
return TRUE;\
|
|
}
|
|
|
|
/*
|
|
* initialize object, must be called from PHP_MINIT_FUNCTION etc
|
|
*/
|
|
#define IMPLEMENT_INIT(name, flags) \
|
|
IMPLEMENT_INIT_EX(name, flags, NULL, _##name##_FunctionCall, _##name##_GetProperty, _##name##_PutProperty)
|
|
|
|
|
|
/*
|
|
* functions to save and retrieve data for the object
|
|
*/
|
|
#define IMPLEMENT_DATA_HELPERS(name, flags)\
|
|
void name##_SaveData(zval * pPhpObject, ##name * pData)\
|
|
{\
|
|
orbit_save_data(pPhpObject, name##_data_type, pData);\
|
|
}\
|
|
##name * name##_RetrieveData(const zval * pPhpObject)\
|
|
{\
|
|
return (##name *)orbit_retrieve_data(pPhpObject, name##_data_type);\
|
|
}
|
|
|
|
/*
|
|
* static declarations for class
|
|
*/
|
|
#define IMPLEMENT_DECLARATIONS(name, flags)\
|
|
static zend_bool name##_Constructor(##name ** ppObject, int parameterCount, const zval ** ppParameters);\
|
|
static zend_bool name##_Destructor(##name * pObject);\
|
|
static zend_bool name##_CallFunction(##name * pObject, const char * pFunctionName, int parameterCount, const zval ** ppParameters, zval * pResult); \
|
|
\
|
|
static int name##_data_type = 0; \
|
|
static zend_class_entry name##_class_entry;
|
|
|
|
/*
|
|
* use this macro in the source file
|
|
*/
|
|
#define IMPLEMENT_CLASS(name, flags) \
|
|
IMPLEMENT_DECLARATIONS(name, flags) \
|
|
IMPLEMENT_FUNCTION_CALL(name, flags) \
|
|
IMPLEMENT_PUT_PROPERTY(name, flags) \
|
|
IMPLEMENT_GET_PROPERTY(name, flags) \
|
|
IMPLEMENT_INIT(name, flags) \
|
|
IMPLEMENT_DATA_HELPERS(name, flags)
|
|
|
|
|
|
#endif /* __orbit_class_h__ */
|
|
|