Back to index

php5  5.3.10
com_misc.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Wez Furlong  <wez@thebrainroom.com>                          |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 /* $Id: com_misc.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024 
00025 #include "php.h"
00026 #include "php_ini.h"
00027 #include "ext/standard/info.h"
00028 #include "php_com_dotnet.h"
00029 #include "php_com_dotnet_internal.h"
00030 #include "Zend/zend_exceptions.h"
00031 
00032 void php_com_throw_exception(HRESULT code, char *message TSRMLS_DC)
00033 {
00034        int free_msg = 0;
00035        if (message == NULL) {
00036               message = php_win_err(code);
00037               free_msg = 1;
00038        }
00039        zend_throw_exception(php_com_exception_class_entry, message, (long)code TSRMLS_CC);
00040        if (free_msg) {
00041               LocalFree(message);
00042        }
00043 }
00044 
00045 PHPAPI void php_com_wrap_dispatch(zval *z, IDispatch *disp,
00046               int codepage TSRMLS_DC)
00047 {
00048        php_com_dotnet_object *obj;
00049 
00050        obj = emalloc(sizeof(*obj));
00051        memset(obj, 0, sizeof(*obj));
00052        obj->code_page = codepage;
00053        obj->ce = php_com_variant_class_entry;
00054        obj->zo.ce = php_com_variant_class_entry;
00055 
00056        VariantInit(&obj->v);
00057        V_VT(&obj->v) = VT_DISPATCH;
00058        V_DISPATCH(&obj->v) = disp;
00059 
00060        IDispatch_AddRef(V_DISPATCH(&obj->v));
00061        IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);
00062 
00063        Z_TYPE_P(z) = IS_OBJECT;
00064        z->value.obj.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC);
00065        z->value.obj.handlers = &php_com_object_handlers;
00066 }
00067 
00068 PHPAPI void php_com_wrap_variant(zval *z, VARIANT *v,
00069               int codepage TSRMLS_DC)
00070 {
00071        php_com_dotnet_object *obj;
00072 
00073        obj = emalloc(sizeof(*obj));
00074        memset(obj, 0, sizeof(*obj));
00075        obj->code_page = codepage;
00076        obj->ce = php_com_variant_class_entry;
00077        obj->zo.ce = php_com_variant_class_entry;
00078 
00079        VariantInit(&obj->v);
00080        VariantCopyInd(&obj->v, v);
00081        obj->modified = 0;
00082 
00083        if ((V_VT(&obj->v) == VT_DISPATCH) && (V_DISPATCH(&obj->v) != NULL)) {
00084               IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);
00085        }
00086 
00087        Z_TYPE_P(z) = IS_OBJECT;
00088        
00089        z->value.obj.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC);
00090        z->value.obj.handlers = &php_com_object_handlers;
00091 }
00092 
00093 /* this is a convenience function for fetching a particular
00094  * element from a (possibly multi-dimensional) safe array */
00095 PHPAPI int php_com_safearray_get_elem(VARIANT *array, VARIANT *dest, LONG dim1 TSRMLS_DC)
00096 {
00097        UINT dims;
00098        LONG lbound, ubound;
00099        LONG indices[1];
00100        VARTYPE vt;
00101        
00102        if (!V_ISARRAY(array)) {
00103               return 0;
00104        }
00105        
00106        dims = SafeArrayGetDim(V_ARRAY(array));
00107 
00108        if (dims != 1) {
00109               php_error_docref(NULL TSRMLS_CC, E_WARNING,
00110                         "Can only handle single dimension variant arrays (this array has %d)", dims);
00111               return 0;
00112        }
00113        
00114        if (FAILED(SafeArrayGetVartype(V_ARRAY(array), &vt)) || vt == VT_EMPTY) {
00115               vt = V_VT(array) & ~VT_ARRAY;
00116        }
00117 
00118        /* determine the bounds */
00119        SafeArrayGetLBound(V_ARRAY(array), 1, &lbound);
00120        SafeArrayGetUBound(V_ARRAY(array), 1, &ubound);
00121        
00122        /* check bounds */
00123        if (dim1 < lbound || dim1 > ubound) {
00124               php_com_throw_exception(DISP_E_BADINDEX, "index out of bounds" TSRMLS_CC);
00125               return 0;
00126        }
00127        
00128        /* now fetch that element */
00129        VariantInit(dest);
00130               
00131        indices[0] = dim1;
00132 
00133        if (vt == VT_VARIANT) {
00134               SafeArrayGetElement(V_ARRAY(array), indices, dest);
00135        } else {
00136               V_VT(dest) = vt;
00137               /* store the value into "lVal" member of the variant.
00138                * This works because it is a union; since we know the variant
00139                * type, we end up with a working variant */
00140               SafeArrayGetElement(V_ARRAY(array), indices, &dest->lVal);
00141        }
00142 
00143        return 1;     
00144 }