summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/rpc/com/com.c170
-rw-r--r--ext/rpc/com/com_wrapper.c6
-rw-r--r--ext/rpc/com/conversion.c33
-rw-r--r--ext/rpc/com/variant.c8
-rw-r--r--ext/rpc/com/variant.h2
-rw-r--r--ext/rpc/handler.h27
-rw-r--r--ext/rpc/php_rpc.h7
-rw-r--r--ext/rpc/rpc.c96
-rw-r--r--ext/rpc/rpc.h11
-rw-r--r--ext/rpc/rpc_proxy.c4
10 files changed, 171 insertions, 193 deletions
diff --git a/ext/rpc/com/com.c b/ext/rpc/com/com.c
index 2d5a81cb2e..bb4a201fcb 100644
--- a/ext/rpc/com/com.c
+++ b/ext/rpc/com/com.c
@@ -36,13 +36,13 @@ static int com_name(rpc_string, rpc_string *, void *, int);
static int com_ctor(rpc_string, void **, int , zval ***);
static int com_dtor(void *);
static int com_describe(rpc_string, void *, char **, unsigned char **);
-static int com_call(rpc_string, void **, zval *, int, zval ***);
-static int com_get(rpc_string, zval *, void **);
-static int com_set(rpc_string, zval *, void **);
-static int com_compare(void **, void **);
-static int com_has_property(rpc_string, void **);
-static int com_unset_property(rpc_string, void **);
-static int com_get_properties(HashTable **, void **);
+static int com_call(rpc_string, void *, zval *, int, zval ***);
+static int com_get(rpc_string, zval *, void *);
+static int com_set(rpc_string, zval *, void *);
+static int com_compare(void *, void *);
+static int com_has_property(rpc_string, void *);
+static int com_unset_property(rpc_string, void *);
+static int com_get_properties(HashTable **, void *);
static PHP_INI_MH(com_typelib_file_change);
@@ -216,13 +216,21 @@ static int com_name(rpc_string hash, rpc_string *name, void *data, int type)
switch (type) {
case CLASS:
{
- OLECHAR *olestr;
+ if (hash.str != NULL) {
+ OLECHAR *olestr;
- StringFromCLSID((CLSID *) hash.str, &olestr);
- name->str = php_OLECHAR_to_char(olestr, &(name->len), CP_ACP, TRUE);
- CoTaskMemFree(olestr);
+ StringFromCLSID((CLSID *) hash.str, &olestr);
+ name->str = php_OLECHAR_to_char(olestr, &(name->len), CP_ACP, TRUE);
+ CoTaskMemFree(olestr);
- return SUCCESS;
+ return SUCCESS;
+ } else {
+ comval *obj = (comval *) data;
+
+ /* try to figure out classname */
+
+ return FAILURE;
+ }
}
case METHOD:
@@ -620,9 +628,8 @@ static int com_describe(rpc_string method_name, void *data, char **arg_types, un
return retval;
}
-static int com_call(rpc_string method_name, void **data, zval *return_value, int num_args, zval **args[])
+static int com_call(rpc_string method_name, void *data, zval *return_value, int num_args, zval **args[])
{
- DISPID dispid;
DISPPARAMS dispparams;
HRESULT hr;
OLECHAR *funcname = NULL;
@@ -630,17 +637,15 @@ static int com_call(rpc_string method_name, void **data, zval *return_value, int
VARIANT result;
int current_arg, current_variant;
char *ErrString = NULL;
- TSRMLS_FETCH();
/* if the length of the name is 0, we are dealing with a pointer to a dispid */
assert(method_name.len == 0);
- dispid = *(DISPID*)method_name.str;
variant_args = num_args ? (VARIANT *) emalloc(sizeof(VARIANT) * num_args) : NULL;
for (current_arg = 0; current_arg < num_args; current_arg++) {
current_variant = num_args - current_arg - 1;
- php_zval_to_variant(*args[current_arg], &variant_args[current_variant], C_CODEPAGE((comval *) *data));
+ php_zval_to_variant(*args[current_arg], &variant_args[current_variant], C_CODEPAGE((comval *) data));
}
dispparams.rgvarg = variant_args;
@@ -650,7 +655,7 @@ static int com_call(rpc_string method_name, void **data, zval *return_value, int
VariantInit(&result);
- hr = php_COM_invoke((comval *) *data, dispid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, &result, &ErrString);
+ hr = php_COM_invoke((comval *) data, *(DISPID*)method_name.str, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, &result, &ErrString);
for (current_arg=0;current_arg<num_args;current_arg++) {
/* don't release IDispatch pointers as they are used afterwards */
@@ -670,45 +675,26 @@ static int com_call(rpc_string method_name, void **data, zval *return_value, int
error_message = php_COM_error_message(hr);
if (ErrString) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Invoke() failed: %s %s", error_message, ErrString);
+ rpc_error(E_WARNING,"Invoke() failed: %s %s", error_message, ErrString);
efree(ErrString);
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Invoke() failed: %s", error_message);
+ rpc_error(E_WARNING,"Invoke() failed: %s", error_message);
}
LocalFree(error_message);
return FAILURE;
}
- RETVAL_VARIANT(&result, C_CODEPAGE((comval *) *data));
+ RETVAL_VARIANT(&result, C_CODEPAGE((comval *) data));
return SUCCESS;
}
-static int com_get(rpc_string property_name, zval *return_value, void **data)
+static int com_get(rpc_string property_name, zval *return_value, void *data)
{
char *ErrString = NULL;
VARIANT *result;
- OLECHAR *propname;
- DISPID dispid;
DISPPARAMS dispparams;
HRESULT hr;
- TSRMLS_FETCH();
-
- /* obtain property handler */
- propname = php_char_to_OLECHAR(property_name.str, property_name.len, CP_ACP, FALSE);
-
- if (FAILED(hr = php_COM_get_ids_of_names((comval *) *data, propname, &dispid))) {
- char *error_message;
-
- efree(propname);
- error_message = php_COM_error_message(hr);
- rpc_error(E_WARNING,"Unable to lookup %s: %s", property_name.str, error_message);
- LocalFree(error_message);
-
- return FAILURE;
- }
-
- efree(propname);
result = (VARIANT *) emalloc(sizeof(VARIANT));
VariantInit(result);
@@ -716,7 +702,7 @@ static int com_get(rpc_string property_name, zval *return_value, void **data)
dispparams.cArgs = 0;
dispparams.cNamedArgs = 0;
- if (FAILED(hr = php_COM_invoke((comval *) data, dispid, DISPATCH_PROPERTYGET, &dispparams, result, &ErrString))) {
+ if (FAILED(hr = php_COM_invoke((comval *) data, *((DISPID *) property_name.str), DISPATCH_PROPERTYGET, &dispparams, result, &ErrString))) {
char *error_message;
efree(result);
@@ -732,51 +718,43 @@ static int com_get(rpc_string property_name, zval *return_value, void **data)
return FAILURE;
}
- RETVAL_VARIANT(result, C_CODEPAGE((comval *) *data));
+ if (V_VT(result) == VT_DISPATCH) {
+ RETVAL_VARIANT(result, C_CODEPAGE((comval *) data));
+ } else {
+ comval *foo = (comval *) data;
+ php_variant_to_zval(result, return_value, C_CODEPAGE(foo));
+ VariantClear(result);
+ }
+
+ efree(result);
return SUCCESS;
}
-static int com_set(rpc_string property_name, zval *value, void **data)
+static int com_set(rpc_string property_name, zval *value, void *data)
{
HRESULT hr;
- OLECHAR *propname;
- DISPID dispid, mydispid = DISPID_PROPERTYPUT;
+ DISPID mydispid = DISPID_PROPERTYPUT;
DISPPARAMS dispparams;
VARIANT *var;
char *error_message, *ErrString = NULL;
- TSRMLS_FETCH();
-
- /* obtain property handler */
- propname = php_char_to_OLECHAR(property_name.str, property_name.len, CP_ACP, FALSE);
-
- if (FAILED(hr = php_COM_get_ids_of_names((comval *) *data, propname, &dispid))) {
- error_message = php_COM_error_message(hr);
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Unable to lookup %s: %s", property_name.str, error_message);
- LocalFree(error_message);
- efree(propname);
-
- return FAILURE;
- }
-
- efree(propname);
var = (VARIANT *) emalloc(sizeof(VARIANT));
VariantInit(var);
- php_zval_to_variant(value, var, C_CODEPAGE((comval *) *data));
+ php_zval_to_variant(value, var, C_CODEPAGE((comval *) data));
dispparams.rgvarg = var;
dispparams.rgdispidNamedArgs = &mydispid;
dispparams.cArgs = 1;
dispparams.cNamedArgs = 1;
- if (FAILED(hr = php_COM_invoke((comval *) *data, dispid, DISPATCH_PROPERTYPUT, &dispparams, NULL, &ErrString))) {
+ if (FAILED(hr = php_COM_invoke((comval *) data, *(DISPID*)property_name.str, DISPATCH_PROPERTYPUT, &dispparams, NULL, &ErrString))) {
error_message = php_COM_error_message(hr);
if (ErrString) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"PropPut() failed: %s %s", error_message, ErrString);
+ rpc_error(E_WARNING,"PropPut() failed: %s %s", error_message, ErrString);
efree(ErrString);
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"PropPut() failed: %s", error_message);
+ rpc_error(E_WARNING,"PropPut() failed: %s", error_message);
}
LocalFree(error_message);
VariantClear(var);
@@ -792,22 +770,22 @@ static int com_set(rpc_string property_name, zval *value, void **data)
return SUCCESS;
}
-static int com_compare(void **data1, void **data2)
+static int com_compare(void *data1, void *data2)
{
return SUCCESS;
}
-static int com_has_property(rpc_string property_name, void **data)
+static int com_has_property(rpc_string property_name, void *data)
{
return SUCCESS;
}
-static int com_unset_property(rpc_string property_name, void **data)
+static int com_unset_property(rpc_string property_name, void *data)
{
return SUCCESS;
}
-static int com_get_properties(HashTable **properties, void **data)
+static int com_get_properties(HashTable **properties, void *data)
{
return SUCCESS;
}
@@ -819,13 +797,11 @@ static int com_get_properties(HashTable **properties, void **data)
Increases the reference counter on a COM object */
ZEND_FUNCTION(com_addref)
{
- zval *object = getThis();
+ zval *object;
rpc_internal *intern;
- if (object == NULL) {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &object, com_class_entry);
- } else {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "");
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, com_class_entry) != SUCCESS) {
+ return;
}
if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
@@ -840,13 +816,11 @@ ZEND_FUNCTION(com_addref)
Releases a COM object */
ZEND_FUNCTION(com_release)
{
- zval *object = getThis();
+ zval *object;
rpc_internal *intern;
- if (object == NULL) {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &object, com_class_entry);
- } else {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "");
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, com_class_entry) != SUCCESS) {
+ return;
}
if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
@@ -859,15 +833,13 @@ ZEND_FUNCTION(com_release)
PHP_FUNCTION(com_next)
{
- zval *object = getThis();
+ zval *object;
rpc_internal *intern;
comval *obj;
unsigned long count = 1;
- if (object == NULL) {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|l", &object, com_class_entry, &count);
- } else {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &count);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &object, com_class_entry, &count) != SUCCESS) {
+ return;
}
if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
@@ -921,7 +893,7 @@ PHP_FUNCTION(com_next)
efree(result);
error_message = php_COM_error_message(hr);
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
+ rpc_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
efree(error_message);
RETURN_NULL();
@@ -968,14 +940,12 @@ PHP_FUNCTION(com_all)
PHP_FUNCTION(com_reset)
{
- zval *object = getThis();
+ zval *object;
rpc_internal *intern;
comval *obj;
- if (object == NULL) {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &object, com_class_entry);
- } else {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "");
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, com_class_entry) != SUCCESS) {
+ return;
}
if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
@@ -989,7 +959,7 @@ PHP_FUNCTION(com_reset)
if (FAILED(hr = C_ENUMVARIANT_VT(obj)->Reset(C_ENUMVARIANT(obj)))) {
char *error_message = php_COM_error_message(hr);
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
+ rpc_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
efree(error_message);
RETURN_FALSE;
@@ -1004,15 +974,13 @@ PHP_FUNCTION(com_reset)
PHP_FUNCTION(com_skip)
{
- zval *object = getThis();
+ zval *object;
rpc_internal *intern;
comval *obj;
unsigned long count = 1;
- if (object == NULL) {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|l", &object, com_class_entry, &count);
- } else {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &count);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &object, com_class_entry, &count) != SUCCESS) {
+ return;
}
if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
@@ -1026,7 +994,7 @@ PHP_FUNCTION(com_skip)
if (FAILED(hr = C_ENUMVARIANT_VT(obj)->Skip(C_ENUMVARIANT(obj), count))) {
char *error_message = php_COM_error_message(hr);
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
+ rpc_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
efree(error_message);
RETURN_FALSE;
}
@@ -1042,13 +1010,11 @@ PHP_FUNCTION(com_skip)
Grabs an IEnumVariant */
ZEND_FUNCTION(com_isenum)
{
- zval *object = getThis();
+ zval *object;
rpc_internal *intern;
- if (object == NULL) {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &object, com_class_entry);
- } else {
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "");
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, com_class_entry) != SUCCESS) {
+ return;
}
if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
diff --git a/ext/rpc/com/com_wrapper.c b/ext/rpc/com/com_wrapper.c
index 552e61c628..b7de426292 100644
--- a/ext/rpc/com/com_wrapper.c
+++ b/ext/rpc/com/com_wrapper.c
@@ -880,7 +880,7 @@ ZEND_API int php_COM_load_typelib(ITypeLib *TypeLib, int mode)
/* Oops, it already exists. No problem if it is defined as the same value */
/* Check to see if they are the same */
if (!compare_function(&results, &c.value, &exists TSRMLS_CC) && INI_INT("com.autoregister_verbose")) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type library value %s is already defined and has a different value", c.name);
+ rpc_error(NULL TSRMLS_CC, E_WARNING, "Type library value %s is already defined and has a different value", c.name);
}
free(c.name);
j++;
@@ -912,13 +912,11 @@ ZEND_API int php_COM_load_typelib(ITypeLib *TypeLib, int mode)
PHPAPI zval *php_COM_object_from_dispatch(IDispatch *disp)
{
comval *obj;
- TSRMLS_FETCH();
ALLOC_COM(obj);
php_COM_set(obj, &disp, FALSE);
- return rpc_object_from_data(NULL, com, obj, NULL);
-
+ return rpc_object_from_data(com, obj);
}
#endif
diff --git a/ext/rpc/com/conversion.c b/ext/rpc/com/conversion.c
index 1d6bcd71cf..fb61c0eeb1 100644
--- a/ext/rpc/com/conversion.c
+++ b/ext/rpc/com/conversion.c
@@ -97,7 +97,6 @@ PHPAPI void php_zval_to_variant(zval *zval_arg, VARIANT *var_arg, int codepage)
PHPAPI void php_zval_to_variant_ex(zval *zval_arg, VARIANT *var_arg, int type, int codepage)
{
OLECHAR *unicode_str = NULL;
- TSRMLS_FETCH();
VariantInit(var_arg);
V_VT(var_arg) = type;
@@ -125,7 +124,7 @@ PHPAPI void php_zval_to_variant_ex(zval *zval_arg, VARIANT *var_arg, int type, i
safeArray = SafeArrayCreate(VT_VARIANT, 1, bounds);
if (NULL == safeArray) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to convert php array to VARIANT array - %s", numberOfElements ? "" : "(Empty input array)");
+ rpc_error(E_WARNING, "Unable to convert php array to VARIANT array - %s", numberOfElements ? "" : "(Empty input array)");
ZVAL_FALSE(zval_arg);
} else {
V_ARRAY(var_arg) = safeArray;
@@ -144,14 +143,14 @@ PHPAPI void php_zval_to_variant_ex(zval *zval_arg, VARIANT *var_arg, int type, i
php_zval_to_variant(*entry, v, codepage); /* Do the required conversion */
}
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "phpArrayToSafeArray() - Unable to retrieve pointer to output element number (%d)", i);
+ rpc_error(E_WARNING, "phpArrayToSafeArray() - Unable to retrieve pointer to output element number (%d)", i);
}
}
zend_hash_move_forward(ht);
}
SafeArrayUnlock( safeArray);
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "phpArrayToSafeArray() - Unable to lock safeArray");
+ rpc_error(E_WARNING, "phpArrayToSafeArray() - Unable to lock safeArray");
}
}
} else {
@@ -366,7 +365,7 @@ PHPAPI void php_zval_to_variant_ex(zval *zval_arg, VARIANT *var_arg, int type, i
break;
case VT_VARIANT:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "VT_VARIANT is invalid. Use VT_VARIANT|VT_BYREF instead.");
+ rpc_error(E_WARNING, "VT_VARIANT is invalid. Use VT_VARIANT|VT_BYREF instead.");
/* break missing intentionally */
case VT_VARIANT|VT_BYREF: {
variantval *var;
@@ -431,7 +430,7 @@ PHPAPI void php_zval_to_variant_ex(zval *zval_arg, VARIANT *var_arg, int type, i
break;
default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported variant type: %d (0x%X)", V_VT(var_arg), V_VT(var_arg));
+ rpc_error(E_WARNING, "Unsupported variant type: %d (0x%X)", V_VT(var_arg), V_VT(var_arg));
}
if (unicode_str != NULL) {
@@ -446,7 +445,6 @@ PHPAPI int php_variant_to_zval(VARIANT *var_arg, zval *zval_arg, int codepage)
/* Existing calls will be unaffected by the change - so it */
/* seemed like the smallest impact on unfamiliar code */
int ret = SUCCESS;
- TSRMLS_FETCH();
INIT_PZVAL(zval_arg);
@@ -465,7 +463,7 @@ PHPAPI int php_variant_to_zval(VARIANT *var_arg, zval *zval_arg, int codepage)
/* TODO: Add support for multi-dimensional SafeArrays */
/* For now just validate that the SafeArray has one dimension */
if (1 != (Dims = SafeArrayGetDim(array))) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported: multi-dimensional (%d) SafeArrays", Dims);
+ rpc_error(E_WARNING, "Unsupported: multi-dimensional (%d) SafeArrays", Dims);
ZVAL_NULL(zval_arg);
return FAILURE;
}
@@ -586,7 +584,7 @@ PHPAPI int php_variant_to_zval(VARIANT *var_arg, zval *zval_arg, int codepage)
default:
ZVAL_NULL(zval_arg);
ret = FAILURE;
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error converting DECIMAL value to PHP string");
+ rpc_error(E_WARNING, "Error converting DECIMAL value to PHP string");
break;
}
}
@@ -689,7 +687,7 @@ PHPAPI int php_variant_to_zval(VARIANT *var_arg, zval *zval_arg, int codepage)
char *error_message;
error_message = php_COM_error_message(hr);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to obtain IDispatch interface: %s", error_message);
+ rpc_error(E_WARNING, "Unable to obtain IDispatch interface: %s", error_message);
LocalFree(error_message);
V_DISPATCH(var_arg) = NULL;
@@ -698,12 +696,13 @@ PHPAPI int php_variant_to_zval(VARIANT *var_arg, zval *zval_arg, int codepage)
/* break missing intentionaly */
case VT_DISPATCH: {
comval *obj;
- TSRMLS_FETCH();
if (V_DISPATCH(var_arg) == NULL) {
ret = FAILURE;
ZVAL_NULL(zval_arg);
} else {
+ TSRMLS_FETCH();
+
ALLOC_COM(obj);
php_COM_set(obj, &V_DISPATCH(var_arg), FALSE);
@@ -754,7 +753,7 @@ PHPAPI int php_variant_to_zval(VARIANT *var_arg, zval *zval_arg, int codepage)
break;
default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported variant type: %d (0x%X)", V_VT(var_arg), V_VT(var_arg));
+ rpc_error(E_WARNING, "Unsupported variant type: %d (0x%X)", V_VT(var_arg), V_VT(var_arg));
ZVAL_NULL(zval_arg);
ret = FAILURE;
break;
@@ -767,7 +766,6 @@ PHPAPI OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage, int
{
BOOL error = FALSE;
OLECHAR *unicode_str;
- TSRMLS_FETCH();
if (strlen == -1) {
/* request needed buffersize */
@@ -793,13 +791,13 @@ PHPAPI OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage, int
if (error) {
switch (GetLastError()) {
case ERROR_NO_UNICODE_TRANSLATION:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "No unicode translation available for the specified string");
+ rpc_error(E_WARNING, "No unicode translation available for the specified string");
break;
case ERROR_INSUFFICIENT_BUFFER:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal Error: Insufficient Buffer");
+ rpc_error(E_WARNING, "Internal Error: Insufficient Buffer");
break;
default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown error in php_char_to_OLECHAR()");
+ rpc_error(E_WARNING, "Unknown error in php_char_to_OLECHAR()");
}
}
@@ -821,11 +819,10 @@ PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int cod
/* convert string */
length = WideCharToMultiByte(codepage, codepage == CP_UTF8 ? 0 : WC_COMPOSITECHECK, unicode_str, -1, C_str, reqSize, NULL, NULL) - 1;
} else {
- TSRMLS_FETCH();
C_str = (char *) pemalloc(sizeof(char), persist);
*C_str = 0;
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error in php_OLECHAR_to_char()");
+ rpc_error(E_WARNING, "Error in php_OLECHAR_to_char()");
}
if (out_length) {
diff --git a/ext/rpc/com/variant.c b/ext/rpc/com/variant.c
index 915f58683d..1193dafa4e 100644
--- a/ext/rpc/com/variant.c
+++ b/ext/rpc/com/variant.c
@@ -39,7 +39,7 @@ static zend_object_value variant_objects_new(zend_class_entry * TSRMLS_DC);
static void variant_objects_delete(void *, zend_object_handle TSRMLS_DC);
/* object handler */
-static zval* variant_read(zval *, zval *, int TSRMLS_DC);
+static zval* variant_read(zval *, zval * TSRMLS_DC);
static void variant_write(zval *, zval *, zval * TSRMLS_DC);
static union _zend_function* variant_get_constructor(zval * TSRMLS_DC);
static zend_class_entry* variant_get_class_entry(zval * TSRMLS_DC);
@@ -242,7 +242,7 @@ static void variant_objects_delete(void *object, zend_object_handle handle TSRML
FREE_VARIANT((variantval *)object);
}
-static zval* variant_read(zval *object, zval *member, int type TSRMLS_DC)
+static zval* variant_read(zval *object, zval *member TSRMLS_DC)
{
variantval *var;
zval *result;
@@ -260,7 +260,7 @@ static zval* variant_read(zval *object, zval *member, int type TSRMLS_DC)
ZVAL_LONG(result, V_VT(var->var));
} else {
ZVAL_FALSE(result);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown member.");
+ rpc_error(NULL TSRMLS_CC, E_WARNING, "Unknown member.");
}
return result;
@@ -280,7 +280,7 @@ static void variant_write(zval *object, zval *member, zval *value TSRMLS_DC)
} else if (zend_hash_find(&types, Z_STRVAL_P(member), Z_STRLEN_P(member) + 1, (void **) &type) == SUCCESS) {
php_zval_to_variant_ex(value, var->var, *type, var->codepage);
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown member.");
+ rpc_error(NULL TSRMLS_CC, E_WARNING, "Unknown member.");
}
}
diff --git a/ext/rpc/com/variant.h b/ext/rpc/com/variant.h
index 81004855bc..8d7a9bc6d6 100644
--- a/ext/rpc/com/variant.h
+++ b/ext/rpc/com/variant.h
@@ -36,7 +36,7 @@
comval *obj; \
ALLOC_COM(obj); \
php_COM_set(obj, &V_DISPATCH(v), TRUE); \
- rpc_object_from_data(z, com, obj, NULL); \
+ rpc_object_from_data_ex(z, com, obj, NULL); \
} else { \
php_variant_to_zval((v), (z), cp); \
VariantClear(v); \
diff --git a/ext/rpc/handler.h b/ext/rpc/handler.h
index 132fcc2b89..a01598113b 100644
--- a/ext/rpc/handler.h
+++ b/ext/rpc/handler.h
@@ -82,13 +82,13 @@ typedef struct _rpc_object_handlers {
int (*rpc_ctor)(rpc_string class_name, void **data, int num_args, zval **args[]);
int (*rpc_dtor)(void *data);
int (*rpc_describe)(rpc_string method_name, void *data, char **arg_types, unsigned char **ref_types);
- int (*rpc_call)(rpc_string method_name, void **data, zval *return_value, int num_args, zval **args[]);
- int (*rpc_get)(rpc_string property_name, zval *return_value, void **data);
- int (*rpc_set)(rpc_string property_name, zval *value, void **data);
- int (*rpc_compare)(void **data1, void **data2);
- int (*rpc_has_property)(rpc_string property_name, void **data);
- int (*rpc_unset_property)(rpc_string property_name, void **data);
- int (*rpc_get_properties)(HashTable **properties, void **data);
+ int (*rpc_call)(rpc_string method_name, void *data, zval *return_value, int num_args, zval **args[]);
+ int (*rpc_get)(rpc_string property_name, zval *return_value, void *data);
+ int (*rpc_set)(rpc_string property_name, zval *value, void *data);
+ int (*rpc_compare)(void *data1, void *data2);
+ int (*rpc_has_property)(rpc_string property_name, void *data);
+ int (*rpc_unset_property)(rpc_string property_name, void *data);
+ int (*rpc_get_properties)(HashTable **properties, void *data);
} rpc_object_handlers;
/* handler entry */
@@ -127,8 +127,17 @@ typedef struct _rpc_proxy {
zend_uint dummy;
} rpc_proxy;
+
+ZEND_API ZEND_FUNCTION(rpc_load);
+ZEND_API ZEND_FUNCTION(rpc_call);
+ZEND_API ZEND_FUNCTION(rpc_set);
+ZEND_API ZEND_FUNCTION(rpc_get);
+ZEND_API ZEND_FUNCTION(rpc_singleton);
+ZEND_API ZEND_FUNCTION(rpc_poolable);
+
ZEND_API rpc_register_layer(rpc_handler_entry *entry TSRMLS_DC);
-ZEND_API zval* _rpc_object_from_data(zval *z, zend_class_entry *ce, void *data, rpc_class_hash *class_hash TSRMLS_DC);
-#define rpc_object_from_data(z, layer, data, class_hash) _rpc_object_from_data((z), layer##_class_entry, (data), (class_hash) TSRMLS_CC)
+ZEND_API zval* _rpc_object_from_data(zval *z, rpc_handler_entry *handler, void *data, rpc_class_hash *class_hash);
+#define rpc_object_from_data(layer, data) rpc_object_from_data_ex(NULL, layer, data, NULL)
+#define rpc_object_from_data_ex(z, layer, data, class_hash) _rpc_object_from_data((z), &layer##_handler_entry, (data), (class_hash))
#endif /* HANDLER_H */ \ No newline at end of file
diff --git a/ext/rpc/php_rpc.h b/ext/rpc/php_rpc.h
index 1e36ece531..16126bc82a 100644
--- a/ext/rpc/php_rpc.h
+++ b/ext/rpc/php_rpc.h
@@ -34,13 +34,6 @@ ZEND_RINIT_FUNCTION(rpc);
ZEND_RSHUTDOWN_FUNCTION(rpc);
ZEND_MINFO_FUNCTION(rpc);
-ZEND_API ZEND_FUNCTION(rpc_load);
-ZEND_API ZEND_FUNCTION(rpc_call);
-ZEND_API ZEND_FUNCTION(rpc_set);
-ZEND_API ZEND_FUNCTION(rpc_get);
-ZEND_API ZEND_FUNCTION(rpc_singleton);
-ZEND_API ZEND_FUNCTION(rpc_poolable);
-
ZEND_API void rpc_error(int type, const char *format, ...);
ZEND_API zend_object_value rpc_objects_new(zend_class_entry * TSRMLS_DC);
diff --git a/ext/rpc/rpc.c b/ext/rpc/rpc.c
index 000f8d7bc3..1eae43234e 100644
--- a/ext/rpc/rpc.c
+++ b/ext/rpc/rpc.c
@@ -36,8 +36,10 @@ static void rpc_string_dtor(void *);
static void rpc_objects_delete(void *, zend_object_handle TSRMLS_DC);
static void rpc_ini_cb(void *arg TSRMLS_DC);
+static rpc_class_hash *rpc_class_hash_find(rpc_string *name);
+
/* object handler */
-static zval* rpc_read(zval *, zval *, int TSRMLS_DC);
+static zval* rpc_read(zval *, zval * TSRMLS_DC);
static void rpc_write(zval *, zval *, zval * TSRMLS_DC);
static zval** rpc_get_property(zval *, zval * TSRMLS_DC);
static zval* rpc_get(zval * TSRMLS_DC);
@@ -283,7 +285,7 @@ static void rpc_objects_delete(void *object, zend_object_handle handle TSRMLS_DC
}
}
-static zval* rpc_read(zval *object, zval *member, int type TSRMLS_DC)
+static zval* rpc_read(zval *object, zval *member TSRMLS_DC)
{
zval *return_value;
GET_INTERNAL(intern);
@@ -439,7 +441,6 @@ ZEND_API ZEND_FUNCTION(rpc_load)
zend_uint num_args = ZEND_NUM_ARGS();
zend_class_entry overloaded_class_entry;
rpc_class_hash *class_hash;
- rpc_class_hash **class_hash_find = NULL;
rpc_internal *intern;
rpc_string hash_val, class_val;
int retval, append = 0;
@@ -493,16 +494,10 @@ ZEND_API ZEND_FUNCTION(rpc_load)
GET_SIGNATURE(intern, class_val.str, class_val.len, hash_val, num_args, arg_types);
/* check if already hashed */
- if (zend_ts_hash_find(&classes, hash_val.str, hash_val.len + 1, (void **) &class_hash_find) != SUCCESS) {
- class_hash = pemalloc(sizeof(rpc_class_hash), TRUE);
+ if ((class_hash = rpc_class_hash_find(&hash_val)) == NULL) {
+ rpc_class_hash **class_hash_find;
- /* set up the cache */
- zend_ts_hash_init(&(class_hash->methods), 0, NULL, rpc_string_dtor, TRUE);
- zend_ts_hash_init(&(class_hash->properties), 0, NULL, rpc_string_dtor, TRUE);
- class_hash->handlers = intern->handlers;
- class_hash->singleton = FALSE;
- class_hash->poolable = FALSE;
- class_hash->data = NULL;
+ ALLOC_CLASS_HASH(class_hash, intern->handlers);
/* do hashing */
if (RPC_HT(intern)->rpc_hash(class_val, (rpc_string *)(class_hash), NULL, num_args, arg_types, CLASS) != SUCCESS) {
@@ -524,8 +519,8 @@ ZEND_API ZEND_FUNCTION(rpc_load)
* also track all instaces in a llist for destruction later on, because there might be duplicate entries in
* the hashtable and we can't determine if a pointer references to an already freed element
*/
- zend_ts_hash_add(&classes, hash_val.str, hash_val.len + 1, &class_hash, sizeof(rpc_class_hash *), (void **) &class_hash_find);
tsrm_mutex_lock(classes.mx_writer);
+ zend_ts_hash_add(&classes, hash_val.str, hash_val.len + 1, &class_hash, sizeof(rpc_class_hash *), (void **) &class_hash_find);
zend_llist_add_element(&classes_list, class_hash_find);
tsrm_mutex_unlock(classes.mx_writer);
@@ -537,7 +532,6 @@ ZEND_API ZEND_FUNCTION(rpc_load)
zend_ts_hash_index_update(&classes, class_hash->name.len, &class_hash, sizeof(rpc_class_hash *), NULL);
}
} else {
- class_hash = *class_hash_find;
intern->ce = class_hash->ce;
}
@@ -551,19 +545,11 @@ ZEND_API ZEND_FUNCTION(rpc_load)
}
} else {
/* integer classname (hashcode) */
- if (zend_ts_hash_index_find(&classes, class_val.len, (void**) &class_hash_find) != SUCCESS) {
- class_hash = pemalloc(sizeof(rpc_class_hash), TRUE);
+ if ((class_hash = rpc_class_hash_find(&hash_val)) == NULL) {
+ ALLOC_CLASS_HASH(class_hash, intern->handlers);
- /* set up the cache */
class_hash->name.str = NULL;
class_hash->name.len = class_val.len;
- class_hash->handlers = intern->handlers;
- class_hash->singleton = FALSE;
- class_hash->poolable = FALSE;
- class_hash->data = NULL;
-
- zend_ts_hash_init(&(class_hash->methods), 0, NULL, rpc_string_dtor, TRUE);
- zend_ts_hash_init(&(class_hash->properties), 0, NULL, rpc_string_dtor, TRUE);
/* overload class entry */
RPC_HT(intern)->rpc_name(class_val, &class_val, NULL, CLASS);
@@ -575,7 +561,6 @@ ZEND_API ZEND_FUNCTION(rpc_load)
/* register int hashcode, we don't know more */
zend_ts_hash_index_update(&classes, class_hash->name.len, &class_hash, sizeof(rpc_class_hash *), NULL);
} else {
- class_hash = *class_hash_find;
intern->ce = class_hash->ce;
}
}
@@ -686,9 +671,10 @@ ZEND_API ZEND_FUNCTION(rpc_call)
/* actually this should not be neccesary, but who knows :)
* considering possible thread implementations in future php versions
* and srm it is better to do concurrency checks
+ * DEPRECATE THIS !
*/
tsrm_mutex_lock(intern->mx_handler);
- retval = RPC_HT(intern)->rpc_call(*method_hash, &(intern->data), return_value, num_args, args);
+ retval = RPC_HT(intern)->rpc_call(*method_hash, intern->data, return_value, num_args, args);
tsrm_mutex_unlock(intern->mx_handler);
}
@@ -789,9 +775,10 @@ ZEND_API ZEND_FUNCTION(rpc_poolable)
ZEND_API void rpc_error(int type, const char *format, ...)
{
va_list args;
+ TSRMLS_FETCH();
va_start(args, format);
- zend_error(type, format, args);
+ zend_error_cb(type, zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C), format, args);
va_end(args);
}
@@ -808,7 +795,6 @@ ZEND_API zend_object_value rpc_objects_new(zend_class_entry *class_type TSRMLS_D
intern->ce = class_type;
intern->data = NULL;
- intern->function_table.hash = intern->ce->function_table;
intern->function_table.reader = 0;
intern->function_table.mx_reader = tsrm_mutex_alloc();
intern->function_table.mx_writer = tsrm_mutex_alloc();
@@ -885,16 +871,37 @@ static void rpc_internal_set(rpc_internal *intern, char *property, zend_uint pro
}
}
-ZEND_API zval* _rpc_object_from_data(zval *z, zend_class_entry *ce, void *data, rpc_class_hash *class_hash TSRMLS_DC)
+static rpc_class_hash *rpc_class_hash_find(rpc_string *name)
+{
+ rpc_class_hash **class_hash_find = NULL;
+
+ if (name->str == NULL) {
+ /* int value */
+ if (zend_ts_hash_index_find(&classes, name->len, (void**) &class_hash_find) != SUCCESS) {
+ return NULL;
+ }
+ } else {
+ /* string value */
+ if (zend_ts_hash_find(&classes, name->str, name->len + 1, (void **) &class_hash_find) != SUCCESS) {
+ return NULL;
+ }
+ }
+
+ return *class_hash_find;
+}
+
+ZEND_API zval* _rpc_object_from_data(zval *z, rpc_handler_entry *handler, void *data, rpc_class_hash *class_hash)
{
rpc_internal *intern;
+ rpc_string name = {NULL, 0};
+ TSRMLS_FETCH();
if (z == NULL) {
ALLOC_ZVAL(z);
}
Z_TYPE_P(z) = IS_OBJECT;
- z->value.obj = rpc_objects_new(ce TSRMLS_CC);
+ z->value.obj = rpc_objects_new(*(handler->ce) TSRMLS_CC);
if (GET_INTERNAL_EX(intern, z) != SUCCESS) {
/* TODO: exception */
@@ -904,24 +911,21 @@ ZEND_API zval* _rpc_object_from_data(zval *z, zend_class_entry *ce, void *data,
intern->data = data;
if (class_hash == NULL) {
- class_hash = pemalloc(sizeof(rpc_class_hash), TRUE);
- if (class_hash == NULL) {
- /* TODO: exception */
+ if (handler->handlers->rpc_name(name, &name, data, CLASS) == SUCCESS) {
+ class_hash = rpc_class_hash_find(&name);
+ } else {
+ ALLOC_CLASS_HASH(class_hash, intern->handlers);
- return NULL;
+ if (class_hash == NULL) {
+ /* TODO: exception */
+ return NULL;
+ }
+
+ /* Copy the function table hash for this object, so that it is separated
+ * from the "global" table */
+ zend_ts_hash_init(&(intern->function_table), 0, NULL, NULL, TRUE);
+ zend_hash_copy(&intern->function_table.hash, &((*(handler->ce))->function_table), NULL, NULL, 0);
}
- /* set up the cache */
- zend_ts_hash_init(&(class_hash->methods), 0, NULL, rpc_string_dtor, TRUE);
- zend_ts_hash_init(&(class_hash->properties), 0, NULL, rpc_string_dtor, TRUE);
- class_hash->handlers = intern->handlers;
- class_hash->singleton = FALSE;
- class_hash->poolable = FALSE;
- class_hash->data = NULL;
-
- /* Copy the function table hash for this object, so that it is separated
- * from the "global" table */
- zend_ts_hash_init(&intern->function_table, 0, NULL, NULL, TRUE);
- zend_hash_copy(&intern->function_table.hash, &ce->function_table, NULL, NULL, 0);
}
RPC_CLASS(intern) = class_hash;
diff --git a/ext/rpc/rpc.h b/ext/rpc/rpc.h
index 7cbb73564f..7a90290a16 100644
--- a/ext/rpc/rpc.h
+++ b/ext/rpc/rpc.h
@@ -123,4 +123,15 @@
efree(arg_types); \
efree(hash_val.str);
+#define ALLOC_CLASS_HASH(_class_hash, _handlers) \
+ if (_class_hash = pemalloc(sizeof(rpc_class_hash), TRUE)) { \
+ /* set up the cache */ \
+ zend_ts_hash_init(&(_class_hash->methods), 0, NULL, rpc_string_dtor, TRUE); \
+ zend_ts_hash_init(&(_class_hash->properties), 0, NULL, rpc_string_dtor, TRUE); \
+ _class_hash->singleton = FALSE; \
+ _class_hash->poolable = FALSE; \
+ _class_hash->data = NULL; \
+ _class_hash->handlers = _handlers; \
+ }
+
#endif \ No newline at end of file
diff --git a/ext/rpc/rpc_proxy.c b/ext/rpc/rpc_proxy.c
index 4699008670..960d89cb49 100644
--- a/ext/rpc/rpc_proxy.c
+++ b/ext/rpc/rpc_proxy.c
@@ -26,7 +26,7 @@ static void rpc_proxy_add_ref(zval * TSRMLS_DC);
static void rpc_proxy_del_ref(zval * TSRMLS_DC);
static void rpc_proxy_delete(zval * TSRMLS_DC);
static zend_object_value rpc_proxy_clone(zval * TSRMLS_DC);
-static zval* rpc_proxy_read(zval *, zval *, int TSRMLS_DC);
+static zval* rpc_proxy_read(zval *, zval * TSRMLS_DC);
static void rpc_proxy_write(zval *, zval *, zval * TSRMLS_DC);
static zval** rpc_proxy_get_property(zval *, zval * TSRMLS_DC);
static zval* rpc_proxy_get(zval * TSRMLS_DC);
@@ -82,7 +82,7 @@ static zend_object_value rpc_proxy_clone(zval *object TSRMLS_DC)
{
}
-static zval* rpc_proxy_read(zval *object, zval *member, int type TSRMLS_DC)
+static zval* rpc_proxy_read(zval *object, zval *member TSRMLS_DC)
{
return NULL;
}