wez             Mon Feb 10 13:37:27 2003 EDT

  Modified files:              
    /php4/ext/rpc/com   com.c 
  Log:
  Implement com_describe
  
Index: php4/ext/rpc/com/com.c
diff -u php4/ext/rpc/com/com.c:1.17 php4/ext/rpc/com/com.c:1.18
--- php4/ext/rpc/com/com.c:1.17 Mon Feb 10 07:33:14 2003
+++ php4/ext/rpc/com/com.c      Mon Feb 10 13:37:27 2003
@@ -17,6 +17,7 @@
  */
 
 #define _WIN32_DCOM
+#define COBJMACROS
 
 #include "../rpc.h"
 #include "../handler.h"
@@ -25,7 +26,7 @@
 #include "com_wrapper.h"
 #include "conversion.h"
 #include "variant.h"
-
+#include "ext/standard/php_smart_str.h"
 #include <oleauto.h>
 
 
@@ -481,9 +482,143 @@
        return SUCCESS;
 }
 
+static inline void vt_type_to_zpp_string(ELEMDESC *elem, smart_str *argtypes_str, 
+unsigned char *argflags)
+{
+       int ref = 0;
+       int nullable = 0;
+       char zppflag = 'z';
+       WORD vt, flags;
+
+       vt = elem->tdesc.vt;
+       flags = elem->paramdesc.wParamFlags;
+
+       if (vt == VT_PTR) {
+               nullable = 1;
+               ref = 0;
+               vt = elem->tdesc.lptdesc->vt;
+       } else {
+               ref = vt & VT_BYREF;
+       }
+       
+       if (vt & VT_ARRAY) {
+               zppflag = 'a';  
+       } else {
+               switch(vt & ~(VT_BYREF | VT_ARRAY)) {
+               case VT_UI1:
+               case VT_UI2:
+               case VT_UI4:
+               case VT_I1:
+               case VT_I2:
+               case VT_I4:
+                       zppflag = 'l';
+                       break;
+
+               case VT_R8:
+               case VT_CY:
+               case VT_DATE:
+                       zppflag = 'd';
+                       break;
+
+               case VT_BSTR:
+                       zppflag = 's';
+                       break;
+
+               case VT_BOOL:
+                       zppflag = 'b';
+                       break;
+
+               case VT_DISPATCH:
+               case VT_UNKNOWN:
+                       zppflag = 'o';
+                       break;
+
+               case VT_VARIANT:
+               default:
+                       zppflag = 'z';
+
+               }
+       }
+
+       smart_str_appendl(argtypes_str, &zppflag, 1);
+       if (ref) {
+               smart_str_appendl(argtypes_str, "/", 1);
+               *argflags = BYREF_FORCE;
+       } else {
+               *argflags = BYREF_NONE;
+       }
+       if (nullable) {
+               smart_str_appendl(argtypes_str, "!", 1);
+       }
+}
+
 static int com_describe(rpc_string method_name, void *data, char **arg_types, 
unsigned char **ref_types)
 {
-       return SUCCESS;
+       rpc_internal *intern;
+       comval *obj;
+       ITypeInfo *typeinfo;
+       FUNCDESC *funcdesc;
+       MEMBERID fid;
+       OLECHAR *olename;
+       int retval = FAILURE, arg_count;
+       int i, type_len = 0;
+       smart_str argtypes_str = {0};
+       unsigned char *func_arg_types;
+       TSRMLS_FETCH();
+
+       GET_INTERNAL_EX(intern, data);
+       obj = (comval*)data;
+
+       if (C_TYPEINFO(obj)) {
+               typeinfo = C_TYPEINFO(obj);
+               ITypeInfo_AddRef(typeinfo);
+       } else if (FAILED(C_DISPATCH_VT(obj)->GetTypeInfo(C_DISPATCH(obj), 0, 
+LOCALE_SYSTEM_DEFAULT, &typeinfo))) {
+               return FAILURE;
+       }
+
+       olename = php_char_to_OLECHAR(method_name.str, method_name.len, CP_ACP, FALSE);
+
+       if (SUCCEEDED(ITypeInfo_GetIDsOfNames(typeinfo, &olename, 1, &fid)) && 
+SUCCEEDED(ITypeInfo_GetFuncDesc(typeinfo, fid, &funcdesc))) {
+
+               arg_count = funcdesc->cParams + (funcdesc->cParamsOpt == -1 ? 1 : 
+funcdesc->cParamsOpt);
+               
+               func_arg_types = (unsigned char*)malloc((1 + arg_count) * 
+sizeof(unsigned char));
+
+               func_arg_types[0] = arg_count;
+
+               /* required parameters first */
+               for (i = 0; i < funcdesc->cParams; i++) {
+                       ELEMDESC *elem = &funcdesc->lprgelemdescParam[i];
+
+                       vt_type_to_zpp_string(elem, &argtypes_str, 
+&func_arg_types[i+1]);
+               }
+
+               if (funcdesc->cParamsOpt == -1) {
+                       /* needs to be a SAFEARRAY of VARIANTS */
+                       smart_str_appendl(&argtypes_str, "|z", 2);
+                       func_arg_types[funcdesc->cParams+1] = BYREF_NONE;
+               } else if (funcdesc->cParamsOpt > 0) {
+                       smart_str_appendl(&argtypes_str, "|", 1);
+
+                       for (i = funcdesc->cParams; i < funcdesc->cParams + 
+funcdesc->cParamsOpt; i++) {
+                               ELEMDESC *elem = &funcdesc->lprgelemdescParam[i];
+
+                               vt_type_to_zpp_string(elem, &argtypes_str, 
+&func_arg_types[i+1]);
+                       }
+               }
+
+               *ref_types = func_arg_types;
+               smart_str_0(&argtypes_str);
+               *arg_types = strdup(argtypes_str.c);
+               smart_str_free(&argtypes_str);
+
+               retval = SUCCESS;
+               ITypeInfo_ReleaseFuncDesc(typeinfo, funcdesc);
+       }
+       
+       efree(olename);
+       ITypeInfo_Release(typeinfo);
+
+       return retval;
 }
 
 static int com_call(rpc_string method_name, void **data, zval *return_value, int 
num_args, zval **args[])



-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to