2424
2525#include "php.h"
2626#include "ext/standard/info.h"
27+ #include "ext/standard/php_var.h"
2728#include "zend_exceptions.h"
2829#include "php_arraylist.h"
2930
3940#endif
4041
4142zend_class_entry * array_list_ce ;
42- zend_object_handlers handler_ArrayList ;
43+ zend_object_handlers handler_array_list ;
4344
4445typedef struct _arraylist { /* {{{ */
4546 size_t nSize ;
@@ -88,9 +89,9 @@ static void arraylist_init(arraylist *array, zend_long size) /* {{{ */
8889{
8990 array -> elements = NULL ;
9091 array -> elements = (zval * )ecalloc (size , sizeof (zval ));
91- array -> nSize = size ;
9292 array -> nNumUsed = 0 ;
9393 array -> nNextIndex = 0 ;
94+ array -> nSize = size ;
9495}
9596/* }}} */
9697
@@ -117,38 +118,39 @@ static void arraylist_resize(arraylist *array) /* {{{ */
117118{
118119 if (array -> nNumUsed == array -> nSize )
119120 {
120- zend_long oldSize = array -> nSize == 1 ? 2 : array -> nSize ;
121- zend_long newSize = oldSize + (oldSize >> 1 );
122- zval * elements ;
123- elements = (zval * )ecalloc (newSize , sizeof (zval ));
124- zend_long i = 0 ;
121+ size_t i = 0 ;
122+ size_t oldSize = array -> nSize == 1 ? 2 : array -> nSize ;
123+ size_t newSize = oldSize + (oldSize >> 1 );
124+ zval * elements = (zval * )ecalloc (newSize , sizeof (zval ));
125125 for (; i < array -> nSize ; i ++ )
126126 {
127127 elements [i ] = array -> elements [i ];
128+ zval_dtor (& array -> elements [i ]);
128129 }
129130 efree (array -> elements );
130131 array -> elements = NULL ;
131132 array -> elements = elements ;
133+ // Z_TRY_ADDREF(elements);
132134 array -> nSize = newSize ;
133135 }
134136}
135137/* }}} */
136138
137139static void arraylist_add (arraylist * array , zval * val ) /* {{{ */
138140{
139- if (! array )
141+ if (array == NULL )
140142 {
141- return ;
142- }
143-
144- // if (& array->elements[array->nNextIndex] != NULL) {
145- // printf("ptr = %p, size =%zu \n", intern, intern->array. nSize);
146- php_debug_zval_dump (& array -> elements [array -> nNextIndex ], 1 );
147- ZVAL_COPY ( & array -> elements [array -> nNextIndex ], val );
148- Z_TRY_ADDREF ( array -> elements [array -> nNextIndex ]);
149- array -> nNextIndex ++ ;
150- array -> nNumUsed ++ ;
151- // }
143+ php_error_docref ( NULL , E_NOTICE , "array cann't be empty." ) ;
144+ return ;
145+ }
146+ // arraylist_resize( array);
147+ // php_printf("nNextIndex=%zu,nSize =%zu \n", array->nNextIndex, array-> nSize);
148+ // php_debug_zval_dump(&array->elements[array->nNextIndex], 1);
149+ Z_TRY_ADDREF ( array -> elements [array -> nNextIndex ]);
150+ ZVAL_ZVAL ( & array -> elements [array -> nNextIndex ], val , 1 , 1 );
151+
152+ array -> nNextIndex ++ ;
153+ array -> nNumUsed ++ ;
152154}
153155
154156
@@ -164,7 +166,9 @@ PHP_METHOD(arraylist, add)
164166 Z_PARAM_ZVAL (val )
165167 ZEND_PARSE_PARAMETERS_END ();
166168
169+
167170 intern = Z_ARRAYLIST_P (object );
171+
168172 arraylist_add (& intern -> array , val );
169173
170174 RETURN_TRUE ;
@@ -184,20 +188,21 @@ PHP_METHOD(arraylist, get)
184188
185189 intern = Z_ARRAYLIST_P (object );
186190
187- if (key <= intern -> array .nSize )
188- {
189- if (& intern -> array .elements [key ] != NULL )
190- {
191- RETURN_ZVAL (& intern -> array .elements [key ], 1 , 1 );
192- } else {
193- RETURN_NULL ();
194- }
195- }
196- else
191+ if (key >= intern -> array .nSize )
197192 {
198- RETURN_NULL ();
199- }
200- }
193+ php_error_docref (NULL , E_NOTICE , "Undefined offset:%ld" , key );
194+ RETURN_NULL ();
195+ }
196+
197+ if (& intern -> array .elements [key ] != NULL )
198+ {
199+ Z_TRY_ADDREF (intern -> array .elements [key ]);
200+ RETURN_ZVAL (& intern -> array .elements [key ], 1 , 0 );
201+ } else {
202+ RETURN_NULL ();
203+ }
204+ }
205+
201206
202207PHP_METHOD (arraylist , count )
203208{
@@ -249,43 +254,27 @@ PHP_METHOD(arraylist, toArray)
249254}
250255/* }}} */
251256
252- static void arraylist_object_free_storage (zend_object * object )/* {{{ */
253- {
254- arraylist_object * intern = arraylist_from_obj (object );
255- arraylist * array = & intern -> array ;
256- if (array -> nSize > 0 )
257- {
258- int i = 0 ;
259- for (; i < array -> nSize ; i ++ )
260- {
261- zval_ptr_dtor (& array -> elements [i ]);
262- }
263- efree (array -> elements );
264- array -> elements = NULL ;
265- array -> nNumUsed = 0 ;
266- array -> nNextIndex = 0 ;
267- }
268- zend_object_std_dtor (& intern -> std );
269- }
270- /* }}} */
271257
272258static void arraylist_destruct (arraylist_object * intern )/* {{{ */
273259{
274260 // arraylist_object *intern = arraylist_from_obj(object);
275261 arraylist * array = & intern -> array ;
276- if (array -> nSize > 0 )
262+ if (array -> elements )
277263 {
278264 int i = 0 ;
279- for (; i < array -> nSize ; i ++ )
265+ for (; i < array -> nNumUsed ; i ++ )
280266 {
281- zval_ptr_dtor (& array -> elements [i ]);
267+ if (& array -> elements [i ]) {
268+ zval_ptr_dtor (& array -> elements [i ]);
269+ }
282270 }
283271 efree (array -> elements );
284272 array -> elements = NULL ;
285- array -> nNumUsed = 0 ;
286- array -> nNextIndex = 0 ;
273+ array -> nNumUsed = 0 ;
274+ array -> nSize = 0 ;
275+ array -> nNextIndex = 0 ;
287276 }
288- zend_object_std_dtor ( & intern -> std );
277+
289278}
290279/* }}} */
291280
@@ -297,7 +286,6 @@ PHP_METHOD(arraylist, __destruct)
297286 return ;
298287 }
299288 intern = Z_ARRAYLIST_P (object );
300-
301289 arraylist_destruct (intern );
302290}
303291
@@ -312,16 +300,26 @@ static const zend_function_entry arraylist_functions[] = {
312300 */
313301static const zend_function_entry arraylist_methods [] = {
314302 PHP_ME (arraylist , __construct , arginfo_arraylist__construct , ZEND_ACC_PUBLIC )
315- PHP_ME (arraylist , add , arginfo_arraylist_add , ZEND_ACC_PUBLIC )
316- PHP_ME (arraylist , get , arginfo_arraylist_get , ZEND_ACC_PUBLIC )
317- PHP_ME (arraylist , count , arginfo_arraylist_void , ZEND_ACC_PUBLIC )
318- PHP_ME (arraylist , toArray , arginfo_arraylist_void , ZEND_ACC_PUBLIC )
319- PHP_ME (arraylist , getSize , arginfo_arraylist_void , ZEND_ACC_PUBLIC )
320- PHP_ME (arraylist , __destruct , arginfo_arraylist_void , ZEND_ACC_PUBLIC )
303+ PHP_ME (arraylist , add , arginfo_arraylist_add , ZEND_ACC_PUBLIC )
304+ PHP_ME (arraylist , get , arginfo_arraylist_get , ZEND_ACC_PUBLIC )
305+ PHP_ME (arraylist , count , arginfo_arraylist_void , ZEND_ACC_PUBLIC )
306+ PHP_ME (arraylist , toArray , arginfo_arraylist_void , ZEND_ACC_PUBLIC )
307+ PHP_ME (arraylist , getSize , arginfo_arraylist_void , ZEND_ACC_PUBLIC )
308+ PHP_ME (arraylist , __destruct , arginfo_arraylist_void , ZEND_ACC_PUBLIC )
321309 PHP_FE_END
322310};
323311/* }}} */
324312
313+ static void arraylist_object_free_storage (zend_object * object )/* {{{ */
314+ {
315+ arraylist_object * intern = arraylist_from_obj (object );
316+ arraylist * array = & intern -> array ;
317+ arraylist_destruct (intern );
318+ zend_object_std_dtor (& intern -> std );
319+ }
320+ /* }}} */
321+
322+
325323/* {{{ PHP_MSHUTDOWN_FUNCTION
326324 */
327325PHP_MSHUTDOWN_FUNCTION (arraylist )
@@ -380,12 +378,12 @@ PHP_MINIT_FUNCTION(arraylist) /* {{{ */ {
380378 INIT_CLASS_ENTRY (ce , "ArrayList" , arraylist_methods ); //注册类及类方法
381379 array_list_ce = zend_register_internal_class (& ce );
382380
383- memcpy (& handler_ArrayList , zend_get_std_object_handlers (), sizeof (zend_object_handlers ));
384- handler_ArrayList .offset = XtOffsetOf (arraylist_object , std );
385- handler_ArrayList .free_obj = arraylist_object_free_storage ;
386-
381+ memcpy (& handler_array_list , zend_get_std_object_handlers (), sizeof (zend_object_handlers ));
382+ handler_array_list .offset = XtOffsetOf (arraylist_object , std );
387383
388-
384+ handler_array_list .clone_obj = zend_objects_clone_obj ;
385+ handler_array_list .free_obj = arraylist_object_free_storage ;
386+ handler_array_list .dtor_obj = zend_objects_destroy_object ;
389387 return SUCCESS ;
390388}
391389/* }}} */
0 commit comments