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 215915e

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

File tree

2 files changed

+54
-114
lines changed

2 files changed

+54
-114
lines changed

‎ext/com_dotnet/com_variant.c‎

Lines changed: 22 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -24,73 +24,54 @@
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);
49+
V_VT(v) = VT_NULL;
50+
return;
5551
}
5652

5753
/* allocate the structure */
5854
bound.lLbound = 0;
59-
bound.cElements = zend_hash_num_elements(Z_ARRVAL_P(z));
55+
bound.cElements = nb_values;
6056
sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
6157

6258
/* get a lock on the array itself */
6359
SafeArrayAccessData(sa, (void **) &va);
6460
va = (VARIANT*)sa->pvData;
6561

6662
/* 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);
63+
zend_ulong index = 0;
64+
zval *value;
65+
ZEND_HASH_FOREACH_NUM_KEY_VAL(ht, index, value) {
7366
if (intindex < bound.cElements) {
74-
php_com_variant_from_zval(&va[intindex], item, codepage);
67+
php_com_variant_from_zval(&va[index], value, codepage);
7568
}
76-
}
69+
}ZEND_HASH_FOREACH_END();
7770

7871
/* Unlock it and stuff it into our variant */
7972
SafeArrayUnaccessData(sa);
8073
V_VT(v) = VT_ARRAY|VT_VARIANT;
8174
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-
}
9475
}
9576

9677
static void php_com_variant_from_zval_ex(VARIANT *v, zval *z, int codepage, VARTYPE vt)
@@ -142,7 +123,7 @@ static void php_com_variant_from_zval_ex(VARIANT *v, zval *z, int codepage, VART
142123

143124
case IS_ARRAY:
144125
/* map as safe array */
145-
safe_array_from_zval(v, z, codepage);
126+
safe_array_from_hashtable(v, Z_ARRVAL_P(z), codepage);
146127
break;
147128

148129
case IS_LONG:

‎ext/com_dotnet/com_wrapper.c‎

Lines changed: 32 additions & 73 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,42 @@ 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-
}
484-
485-
zend_hash_move_forward_ex(&Z_OBJCE(disp->object)->function_table, &pos);
456+
ZEND_HASH_FOREACH_STR_KEY(&Z_OBJCE(disp->object)->function_table, name) {
457+
ZEND_ASSERT(name);
486458

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);
465+
ZVAL_STR_COPY(&tmp, name);
466+
pid = zend_hash_next_free_element(disp->dispid_to_name);
467+
zend_hash_index_update(disp->dispid_to_name, pid, &tmp);
500468

501-
zend_string_release_ex(name, 0);
502-
}
469+
ZVAL_LONG(&tmp, pid);
470+
zend_hash_update(disp->name_to_dispid, name, &tmp);
471+
} ZEND_HASH_FOREACH_END();
503472
}
504473
}
505474

@@ -540,15 +509,9 @@ static void disp_destructor(php_dispatchex *disp)
540509
CoTaskMemFree(disp);
541510
}
542511

543-
PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *sinkid,
544-
HashTable *id_to_name)
512+
PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *sinkid, HashTable *id_to_name)
545513
{
546514
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;
552515

553516
disp->dispid_to_name = id_to_name;
554517

@@ -558,20 +521,16 @@ PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *si
558521
ALLOC_HASHTABLE(disp->name_to_dispid);
559522
zend_hash_init(disp->name_to_dispid, 0, NULL, ZVAL_PTR_DTOR, 0);
560523

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-
}
524+
ZEND_ASSERT(zend_array_is_list(id_to_name));
525+
zend_ulong pid;
526+
zval *value;
527+
ZEND_HASH_FOREACH_NUM_KEY_VAL(id_to_name, pid, value) {
528+
ZEND_ASSERT(Z_TYPE_P(value) == IS_STRING);
529+
530+
zval tmp;
531+
ZVAL_LONG(&tmp, pid);
532+
zend_hash_update(disp->name_to_dispid, Z_STR_P(value), &tmp);
533+
} ZEND_HASH_FOREACH_END();
575534

576535
return (IDispatch*)disp;
577536
}

0 commit comments

Comments
(0)

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