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 d90ab53

Browse files
committed
ext/com_dotnet: Use modern HashTable APIs
1 parent e3bcbb2 commit d90ab53

File tree

2 files changed

+50
-112
lines changed

2 files changed

+50
-112
lines changed

‎ext/com_dotnet/com_variant.c‎

Lines changed: 20 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -24,72 +24,51 @@
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. If the array
3030
* is sparse, then the gaps will be filled with NULL variants */
31-
static void safe_array_from_zval(VARIANT *v, zval*z, int codepage)
31+
static void safe_array_from_hashtable(VARIANT *v, HashTable*ht, int codepage)
3232
{
3333
SAFEARRAY *sa = NULL;
3434
SAFEARRAYBOUND bound;
35-
HashPosition pos;
36-
int keytype;
37-
zend_string *strindex;
38-
zend_ulong intindex = 0;
3935
VARIANT *va;
40-
zval *item;
4136

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

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

5852
/* allocate the structure */
5953
bound.lLbound = 0;
60-
bound.cElements = zend_hash_num_elements(Z_ARRVAL_P(z));
54+
bound.cElements = nb_values;
6155
sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
6256

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

6761
/* now fill it in */
68-
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(z), &pos);
69-
for (;; zend_hash_move_forward_ex(Z_ARRVAL_P(z), &pos)) {
70-
if (NULL == (item = zend_hash_get_current_data_ex(Z_ARRVAL_P(z), &pos))) {
71-
break;
72-
}
73-
zend_hash_get_current_key_ex(Z_ARRVAL_P(z), &strindex, &intindex, &pos);
74-
php_com_variant_from_zval(&va[intindex], item, codepage);
75-
}
62+
zend_ulong index = 0;
63+
zval *value;
64+
ZEND_HASH_FOREACH_NUM_KEY_VAL(ht, index, value) {
65+
php_com_variant_from_zval(&va[index], value, codepage);
66+
} ZEND_HASH_FOREACH_END();
7667

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

9574
static void php_com_variant_from_zval_ex(VARIANT *v, zval *z, int codepage, VARTYPE vt)
@@ -141,7 +120,7 @@ static void php_com_variant_from_zval_ex(VARIANT *v, zval *z, int codepage, VART
141120

142121
case IS_ARRAY:
143122
/* map as safe array */
144-
safe_array_from_zval(v, z, codepage);
123+
safe_array_from_hashtable(v, Z_ARRVAL_P(z), codepage);
145124
break;
146125

147126
case IS_LONG:

‎ext/com_dotnet/com_wrapper.c‎

Lines changed: 30 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -421,10 +421,8 @@ static struct IDispatchExVtbl php_dispatch_vtbl = {
421421
* dispatch ids */
422422
static void generate_dispids(php_dispatchex *disp)
423423
{
424-
HashPosition pos;
425424
zend_string *name = NULL;
426-
zval *tmp, tmp2;
427-
int keytype;
425+
zval tmp;
428426
zend_ulong pid;
429427

430428
if (disp->dispid_to_name == NULL) {
@@ -436,71 +434,42 @@ static void generate_dispids(php_dispatchex *disp)
436434

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

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

459445
/* add the mappings */
460-
ZVAL_STR_COPY(&tmp2, name);
446+
ZVAL_STR_COPY(&tmp, name);
461447
pid = zend_hash_next_free_element(disp->dispid_to_name);
462-
zend_hash_index_update(disp->dispid_to_name, pid, &tmp2);
463-
464-
ZVAL_LONG(&tmp2, pid);
465-
zend_hash_update(disp->name_to_dispid, name, &tmp2);
448+
zend_hash_index_update(disp->dispid_to_name, pid, &tmp);
466449

467-
zend_string_release_ex(name, 0);
468-
}
450+
ZVAL_LONG(&tmp, pid);
451+
zend_hash_update(disp->name_to_dispid, name, &tmp);
452+
} ZEND_HASH_FOREACH_END();
469453
}
470454

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

488-
/* Find the existing id */
489-
if ((tmp = zend_hash_find(disp->name_to_dispid, name)) != NULL) {
490-
zend_string_release_ex(name, 0);
460+
/* Check ID exists */
461+
if (!zend_hash_exists(disp->name_to_dispid, name)) {
491462
continue;
492463
}
493464

494465
/* add the mappings */
495-
ZVAL_STR_COPY(&tmp2, name);
466+
ZVAL_STR_COPY(&tmp, name);
496467
pid = zend_hash_next_free_element(disp->dispid_to_name);
497-
zend_hash_index_update(disp->dispid_to_name, pid, &tmp2);
498-
499-
ZVAL_LONG(&tmp2, pid);
500-
zend_hash_update(disp->name_to_dispid, name, &tmp2);
468+
zend_hash_index_update(disp->dispid_to_name, pid, &tmp);
501469

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

@@ -541,15 +510,9 @@ static void disp_destructor(php_dispatchex *disp)
541510
CoTaskMemFree(disp);
542511
}
543512

544-
PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *sinkid,
545-
HashTable *id_to_name)
513+
PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *sinkid, HashTable *id_to_name)
546514
{
547515
php_dispatchex *disp = disp_constructor(val);
548-
HashPosition pos;
549-
zend_string *name = NULL;
550-
zval tmp, *ntmp;
551-
int keytype;
552-
zend_ulong pid;
553516

554517
disp->dispid_to_name = id_to_name;
555518

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

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

577536
return (IDispatch*)disp;
578537
}

0 commit comments

Comments
(0)

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