Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 362f64a

Browse files
committed
ext/com_dotnet: Use modern HashTable APIs
1 parent 1331a61 commit 362f64a

File tree

2 files changed

+49
-115
lines changed

2 files changed

+49
-115
lines changed

‎ext/com_dotnet/com_variant.c‎

Lines changed: 20 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -24,73 +24,52 @@
2424
#include "php_com_dotnet.h"
2525
#include "php_com_dotnet_internal.h"
2626

27-
/* create an automation SafeArray from a PHP array.
27+
/* create an automation SafeArray from a PHP array (HashTable).
2828
* Only creates a single-dimensional array of variants.
2929
* The keys of the PHP hash MUST be numeric. */
30-
static void safe_array_from_zval(VARIANT *v, zval*z, int codepage)
30+
static void safe_array_from_hashtable(VARIANT *v, HashTable*ht, int codepage)
3131
{
3232
SAFEARRAY *sa = NULL;
3333
SAFEARRAYBOUND bound;
34-
HashPosition pos;
35-
int keytype;
36-
zend_string *strindex;
37-
zend_ulong intindex = 0;
3834
VARIANT *va;
39-
zval *item;
4035

4136
/* find the largest array index, and assert that all keys are integers */
42-
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(z), &pos);
43-
for (;; zend_hash_move_forward_ex(Z_ARRVAL_P(z), &pos)) {
44-
45-
keytype = zend_hash_get_current_key_ex(Z_ARRVAL_P(z), &strindex, &intindex, &pos);
37+
if (!zend_array_is_list(ht)) {
38+
// TODO: Make this a ValueError
39+
php_error_docref(NULL, E_WARNING, "COM: converting from PHP array to VARIANT array; only arrays with numeric keys are allowed");
40+
V_VT(v) = VT_NULL;
41+
return;
42+
}
43+
// TODO: Check not empty?
4644

47-
if (HASH_KEY_IS_STRING == keytype) {
48-
goto bogus;
49-
} else if (HASH_KEY_NON_EXISTENT == keytype) {
50-
break;
51-
} else if (intindex > UINT_MAX) {
52-
php_error_docref(NULL, E_WARNING, "COM: max number %u of elements in safe array exceeded", UINT_MAX);
53-
break;
54-
}
45+
uint32_t nb_values = zend_hash_num_elements(ht);
46+
if (nb_values > UINT_MAX) {
47+
// TODO: Make this a ValueError?
48+
php_error_docref(NULL, E_WARNING, "COM: max number %u of elements in safe array exceeded", UINT_MAX);
5549
}
5650

5751
/* allocate the structure */
5852
bound.lLbound = 0;
59-
bound.cElements = zend_hash_num_elements(Z_ARRVAL_P(z));
53+
bound.cElements = nb_values;
6054
sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
6155

6256
/* get a lock on the array itself */
6357
SafeArrayAccessData(sa, (void **) &va);
6458
va = (VARIANT*)sa->pvData;
6559

6660
/* now fill it in */
67-
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(z), &pos);
68-
for (;; zend_hash_move_forward_ex(Z_ARRVAL_P(z), &pos)) {
69-
if (NULL == (item = zend_hash_get_current_data_ex(Z_ARRVAL_P(z), &pos))) {
70-
break;
71-
}
72-
zend_hash_get_current_key_ex(Z_ARRVAL_P(z), &strindex, &intindex, &pos);
61+
zend_ulong index = 0;
62+
zval *value;
63+
ZEND_HASH_FOREACH_NUM_KEY_VAL(ht, index, value) {
7364
if (intindex < bound.cElements) {
74-
php_com_variant_from_zval(&va[intindex], item, codepage);
65+
php_com_variant_from_zval(&va[index], value, codepage);
7566
}
76-
}
67+
}ZEND_HASH_FOREACH_END();
7768

7869
/* Unlock it and stuff it into our variant */
7970
SafeArrayUnaccessData(sa);
8071
V_VT(v) = VT_ARRAY|VT_VARIANT;
8172
V_ARRAY(v) = sa;
82-
83-
return;
84-
85-
bogus:
86-
php_error_docref(NULL, E_WARNING, "COM: converting from PHP array to VARIANT array; only arrays with numeric keys are allowed");
87-
88-
V_VT(v) = VT_NULL;
89-
90-
if (sa) {
91-
SafeArrayUnlock(sa);
92-
SafeArrayDestroy(sa);
93-
}
9473
}
9574

9675
static void php_com_variant_from_zval_ex(VARIANT *v, zval *z, int codepage, VARTYPE vt)
@@ -142,7 +121,7 @@ static void php_com_variant_from_zval_ex(VARIANT *v, zval *z, int codepage, VART
142121

143122
case IS_ARRAY:
144123
/* map as safe array */
145-
safe_array_from_zval(v, z, codepage);
124+
safe_array_from_hashtable(v, Z_ARRVAL_P(z), codepage);
146125
break;
147126

148127
case IS_LONG:

‎ext/com_dotnet/com_wrapper.c‎

Lines changed: 29 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -420,10 +420,8 @@ static struct IDispatchExVtbl php_dispatch_vtbl = {
420420
* dispatch ids */
421421
static void generate_dispids(php_dispatchex *disp)
422422
{
423-
HashPosition pos;
424423
zend_string *name = NULL;
425-
zval *tmp, tmp2;
426-
int keytype;
424+
zval tmp;
427425
zend_long pid;
428426

429427
if (disp->dispid_to_name == NULL) {
@@ -435,71 +433,38 @@ static void generate_dispids(php_dispatchex *disp)
435433

436434
/* properties */
437435
if (Z_OBJPROP(disp->object)) {
438-
zend_hash_internal_pointer_reset_ex(Z_OBJPROP(disp->object), &pos);
439-
while (HASH_KEY_NON_EXISTENT != (keytype =
440-
zend_hash_get_current_key_ex(Z_OBJPROP(disp->object), &name,
441-
&pid, &pos))) {
442-
char namebuf[32];
443-
if (keytype == HASH_KEY_IS_LONG) {
444-
snprintf(namebuf, sizeof(namebuf), ZEND_ULONG_FMT, pid);
445-
name = zend_string_init(namebuf, strlen(namebuf), 0);
446-
} else {
447-
zend_string_addref(name);
448-
}
449-
450-
zend_hash_move_forward_ex(Z_OBJPROP(disp->object), &pos);
436+
ZEND_HASH_FOREACH_STR_KEY(Z_OBJPROP(disp->object), name) {
437+
ZEND_ASSERT(name);
451438

452-
/* Find the existing id */
453-
if ((tmp = zend_hash_find(disp->name_to_dispid, name)) != NULL) {
454-
zend_string_release_ex(name, 0);
439+
/* Check ID exists */
440+
if (!zend_hash_exists(disp->name_to_dispid, name)) {
455441
continue;
456442
}
457443

458444
/* add the mappings */
459-
ZVAL_STR_COPY(&tmp2, name);
460-
zend_hash_next_index_insert(disp->dispid_to_name, &tmp2);
461-
pid = zend_hash_next_free_element(disp->dispid_to_name) - 1;
462-
463-
ZVAL_LONG(&tmp2, pid);
464-
zend_hash_update(disp->name_to_dispid, name, &tmp2);
445+
ZVAL_STR_COPY(&tmp, name);
446+
pid = zend_hash_next_free_element(disp->dispid_to_name);
447+
zend_hash_index_update(disp->dispid_to_name, pid, &tmp);
465448

466-
zend_string_release_ex(name, 0);
467-
}
449+
ZVAL_LONG(&tmp, pid);
450+
zend_hash_update(disp->name_to_dispid, name, &tmp);
451+
} ZEND_HASH_FOREACH_END();
468452
}
469453

470454
/* functions */
471455
if (Z_OBJCE(disp->object)) {
472-
zend_hash_internal_pointer_reset_ex(&Z_OBJCE(disp->object)->function_table, &pos);
473-
while (HASH_KEY_NON_EXISTENT != (keytype =
474-
zend_hash_get_current_key_ex(&Z_OBJCE(disp->object)->function_table,
475-
&name, &pid, &pos))) {
476-
477-
char namebuf[32];
478-
if (keytype == HASH_KEY_IS_LONG) {
479-
snprintf(namebuf, sizeof(namebuf), ZEND_ULONG_FMT, pid);
480-
name = zend_string_init(namebuf, strlen(namebuf), 0);
481-
} else {
482-
zend_string_addref(name);
483-
}
456+
ZEND_HASH_FOREACH_STR_KEY(&Z_OBJCE(disp->object)->function_table, name) {
457+
ZEND_ASSERT(name);
484458

485-
zend_hash_move_forward_ex(&Z_OBJCE(disp->object)->function_table, &pos);
486-
487-
/* Find the existing id */
488-
if ((tmp = zend_hash_find(disp->name_to_dispid, name)) != NULL) {
489-
zend_string_release_ex(name, 0);
459+
/* Check ID exists */
460+
if (!zend_hash_exists(disp->name_to_dispid, name)) {
490461
continue;
491462
}
492463

493464
/* add the mappings */
494-
ZVAL_STR_COPY(&tmp2, name);
495-
zend_hash_next_index_insert(disp->dispid_to_name, &tmp2);
496-
pid = zend_hash_next_free_element(disp->dispid_to_name) - 1;
497-
498-
ZVAL_LONG(&tmp2, pid);
499-
zend_hash_update(disp->name_to_dispid, name, &tmp2);
500-
501-
zend_string_release_ex(name, 0);
502-
}
465+
ZVAL_LONG(&tmp, pid);
466+
zend_hash_update(disp->name_to_dispid, name, &tmp);
467+
} ZEND_HASH_FOREACH_END();
503468
}
504469
}
505470

@@ -540,15 +505,9 @@ static void disp_destructor(php_dispatchex *disp)
540505
CoTaskMemFree(disp);
541506
}
542507

543-
PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *sinkid,
544-
HashTable *id_to_name)
508+
PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *sinkid, HashTable *id_to_name)
545509
{
546510
php_dispatchex *disp = disp_constructor(val);
547-
HashPosition pos;
548-
zend_string *name = NULL;
549-
zval tmp, *ntmp;
550-
int keytype;
551-
zend_ulong pid;
552511

553512
disp->dispid_to_name = id_to_name;
554513

@@ -558,20 +517,16 @@ PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *si
558517
ALLOC_HASHTABLE(disp->name_to_dispid);
559518
zend_hash_init(disp->name_to_dispid, 0, NULL, ZVAL_PTR_DTOR, 0);
560519

561-
zend_hash_internal_pointer_reset_ex(id_to_name, &pos);
562-
while (HASH_KEY_NON_EXISTENT != (keytype =
563-
zend_hash_get_current_key_ex(id_to_name, &name, &pid, &pos))) {
564-
565-
if (keytype == HASH_KEY_IS_LONG) {
566-
567-
ntmp = zend_hash_get_current_data_ex(id_to_name, &pos);
568-
569-
ZVAL_LONG(&tmp, pid);
570-
zend_hash_update(disp->name_to_dispid, Z_STR_P(ntmp), &tmp);
571-
}
572-
573-
zend_hash_move_forward_ex(id_to_name, &pos);
574-
}
520+
ZEND_ASSERT(zend_array_is_list(id_to_name));
521+
zend_ulong pid;
522+
zval *value;
523+
ZEND_HASH_FOREACH_NUM_KEY_VAL(id_to_name, pid, value) {
524+
ZEND_ASSERT(Z_TYPE_P(value) == IS_STRING);
525+
526+
zval tmp;
527+
ZVAL_LONG(&tmp, pid);
528+
zend_hash_update(disp->name_to_dispid, Z_STR_P(value), &tmp);
529+
} ZEND_HASH_FOREACH_END();
575530

576531
return (IDispatch*)disp;
577532
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /