Part of Slepp's ProjectsPastebinTURLImagebinFilebin
Feedback -- English French German Japanese
Create Upload Newest Tools Donate
Sign In | Create Account

Advertising

Paste Description for rewbs

Patch to make ArrayObject::exchangeArray use the same logic as ArrayObject::__construct

rewbs
Sunday, August 3rd, 2008 at 4:03:49am MDT 

  1. Index: spl_array.c
  2. ===================================================================
  3. RCS file: /repository/php-src/ext/spl/spl_array.c,v
  4. retrieving revision 1.71.2.17.2.13.2.19
  5. diff -u -w -p -r1.71.2.17.2.13.2.19 spl_array.c
  6. --- spl_array.c 26 Jul 2008 12:34:10 -0000       1.71.2.17.2.13.2.19
  7. +++ spl_array.c 3 Aug 2008 09:59:32 -0000
  8. @@ -924,50 +924,16 @@ zend_object_iterator *spl_array_get_iter
  9.  }
  10.  /* }}} */
  11.  
  12. -/* {{{ proto void ArrayObject::__construct(array|object ar = array() [, int flags = 0 [, string iterator_class = "ArrayIterator"]])
  13. -       proto void ArrayIterator::__construct(array|object ar = array() [, int flags = 0])
  14. - Cronstructs a new array iterator from a path. */
  15. -SPL_METHOD(Array, __construct)
  16. -{
  17. -       zval *object = getThis();
  18. -       spl_array_object *intern;
  19. -       zval **array;
  20. -       long ar_flags = 0;
  21. -       char *class_name;
  22. -       int class_name_len;
  23. -       zend_class_entry ** pce_get_iterator;
  24. -
  25. -       if (ZEND_NUM_ARGS() == 0) {
  26. -              return; /* nothing to do */
  27. -       }
  28. -       php_set_error_handling(EH_THROW, spl_ce_InvalidArgumentException TSRMLS_CC);
  29. -
  30. -       intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
  31. -
  32. -       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|ls", &array, &ar_flags, &class_name, &class_name_len) == FAILURE) {
  33. -              php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  34. -              return;
  35. -       }
  36. +/* {{{ spl_array_set_array */
  37. +static void spl_array_set_array(zval *object, spl_array_object *intern, zval **array, long ar_flags, int just_array TSRMLS_DC) {
  38.  
  39.         if (Z_TYPE_PP(array) == IS_ARRAY) {
  40.                SEPARATE_ZVAL_IF_NOT_REF(array);
  41.         }
  42.  
  43. -       if (ZEND_NUM_ARGS() > 2) {
  44. -              if (zend_lookup_class(class_name, class_name_len, &pce_get_iterator TSRMLS_CC) == FAILURE) {
  45. -                     zend_throw_exception(spl_ce_InvalidArgumentException, "A class that implements Iterator must be specified", 0 TSRMLS_CC);
  46. -                     php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  47. -                     return;
  48. -              }
  49. -              intern->ce_get_iterator = *pce_get_iterator;
  50. -       }
  51. -
  52. -       ar_flags &= ~SPL_ARRAY_INT_MASK;
  53. -
  54.         if (Z_TYPE_PP(array) == IS_OBJECT && (Z_OBJ_HT_PP(array) == &spl_handler_ArrayObject || Z_OBJ_HT_PP(array) == &spl_handler_ArrayIterator)) {
  55.                zval_ptr_dtor(&intern->array);
  56. -              if (ZEND_NUM_ARGS() == 1)
  57. -              {
  58. +              if (just_array)        {
  59.                       spl_array_object *other = (spl_array_object*)zend_object_store_get_object(*array TSRMLS_CC);
  60.                       ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK;
  61.                }           
  62. @@ -996,9 +962,50 @@ SPL_METHOD(Array, __construct)
  63.                || !spl_array_get_hash_table(intern, 0 TSRMLS_CC)) {
  64.                       php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  65.                       zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Overloaded object of type %s is not compatible with %s", Z_OBJCE_PP(array)->name, intern->std.ce->name);
  66. +              }
  67. +       }
  68. +
  69. +       spl_array_rewind(intern TSRMLS_CC);
  70. +}
  71. +/* }}} */
  72. +
  73. +/* {{{ proto void ArrayObject::__construct(array|object ar = array() [, int flags = 0 [, string iterator_class = "ArrayIterator"]])
  74. +       proto void ArrayIterator::__construct(array|object ar = array() [, int flags = 0])
  75. + Cronstructs a new array iterator from a path. */
  76. +SPL_METHOD(Array, __construct)
  77. +{
  78. +       zval *object = getThis();
  79. +       spl_array_object *intern;
  80. +       zval **array;
  81. +       long ar_flags = 0;
  82. +       char *class_name;
  83. +       int class_name_len;
  84. +       zend_class_entry ** pce_get_iterator;
  85. +
  86. +       if (ZEND_NUM_ARGS() == 0) {
  87. +              return; /* nothing to do */
  88. +       }
  89. +       php_set_error_handling(EH_THROW, spl_ce_InvalidArgumentException TSRMLS_CC);
  90. +
  91. +       intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
  92. +
  93. +       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|ls", &array, &ar_flags, &class_name, &class_name_len) == FAILURE) {
  94. +              php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  95.                       return;
  96.                }
  97. +
  98. +       if (ZEND_NUM_ARGS() > 2) {
  99. +              if (zend_lookup_class(class_name, class_name_len, &pce_get_iterator TSRMLS_CC) == FAILURE) {
  100. +                     zend_throw_exception(spl_ce_InvalidArgumentException, "A class that implements Iterator must be specified", 0 TSRMLS_CC);
  101. +                     php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  102. +                     return;
  103.         }
  104. +              intern->ce_get_iterator = *pce_get_iterator;
  105. +       }
  106. +
  107. +       ar_flags &= ~SPL_ARRAY_INT_MASK;
  108. +
  109. +       spl_array_set_array(object, intern, array, ar_flags, ZEND_NUM_ARGS() == 1 TSRMLS_CC);
  110.  
  111.         spl_array_rewind(intern TSRMLS_CC);
  112.  
  113. @@ -1081,31 +1088,9 @@ SPL_METHOD(Array, exchangeArray)
  114.         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &array) == FAILURE) {
  115.                return;
  116.         }
  117. -       if (Z_TYPE_PP(array) == IS_OBJECT && intern == (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC)) {
  118. -              zval_ptr_dtor(&intern->array);
  119. -              array = &object;
  120. -              intern->array = object;
  121. -       } else if (Z_TYPE_PP(array) == IS_OBJECT && (Z_OBJ_HT_PP(array) == &spl_handler_ArrayObject || Z_OBJ_HT_PP(array) == &spl_handler_ArrayIterator)) {
  122. -              spl_array_object *other  = (spl_array_object*)zend_object_store_get_object(*array TSRMLS_CC);
  123. -              zval_ptr_dtor(&intern->array);
  124. -              intern->array = other->array;
  125. -       } else {
  126. -              if (Z_TYPE_PP(array) != IS_OBJECT && !HASH_OF(*array)) {
  127. -                     zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object, using empty array instead", 0 TSRMLS_CC);
  128. -                     return;
  129. -              }
  130. -              zval_ptr_dtor(&intern->array);
  131. -              intern->array = *array;
  132. -              intern->ar_flags &= ~SPL_ARRAY_USE_OTHER;
  133. -       }
  134. -       if (object == *array) {
  135. -              intern->ar_flags |= SPL_ARRAY_IS_SELF;
  136. -       } else {
  137. -              intern->ar_flags &= ~SPL_ARRAY_IS_SELF;
  138. -       }
  139. -       Z_ADDREF_P(intern->array);
  140.  
  141. -       spl_array_rewind(intern TSRMLS_CC);
  142. +       spl_array_set_array(object, intern, array, 0L, 1 TSRMLS_CC);
  143. +
  144.  }
  145.  /* }}} */
  146.  
  147. Index: tests/arrayObject_exchange_basic1.phpt
  148. ===================================================================
  149. RCS file: tests/arrayObject_exchange_basic1.phpt
  150. diff -N tests/arrayObject_exchange_basic1.phpt
  151. --- /dev/null   1 Jan 1970 00:00:00 -0000
  152. +++ tests/arrayObject_exchange_basic1.phpt      3 Aug 2008 09:44:39 -0000
  153. @@ -0,0 +1,40 @@
  154. +--TEST--
  155. +ArrayObject::exchange() and copy-on-write references
  156. +--FILE--
  157. +<?php
  158. +$ao = new ArrayObject();
  159. +$swapIn = array();
  160. +$cowRef = $swapIn; // create a copy-on-write ref to $swapIn
  161. +$ao->exchangeArray($swapIn);
  162. +
  163. +$ao['a'] = 'adding element to $ao';
  164. +$swapIn['b'] = 'adding element to $swapIn';
  165. +$ao['c'] = 'adding another element to $ao';
  166. +
  167. +echo "\n--> swapIn:  ";
  168. +var_dump($swapIn);
  169. +
  170. +echo "\n--> cowRef:  ";
  171. +var_dump($cowRef);
  172. +
  173. +echo "\n--> ao:  ";
  174. +var_dump($ao);
  175. +?>
  176. +--EXPECTF--
  177. +--> swapIn:  array(1) {
  178. ["b"]=>
  179. +  string(25) "adding element to $swapIn"
  180. +}
  181. +
  182. +--> cowRef:  array(0) {
  183. +}
  184. +
  185. +--> ao:  object(ArrayObject)#%d (1) {
  186. ["storage":"ArrayObject":private]=>
  187. +  array(2) {
  188. +    ["a"]=>
  189. +    string(21) "adding element to $ao"
  190. +    ["c"]=>
  191. +    string(29) "adding another element to $ao"
  192. }
  193. +}
  194. Index: tests/arrayObject_exchange_basic2.phpt
  195. ===================================================================
  196. RCS file: tests/arrayObject_exchange_basic2.phpt
  197. diff -N tests/arrayObject_exchange_basic2.phpt
  198. --- /dev/null   1 Jan 1970 00:00:00 -0000
  199. +++ tests/arrayObject_exchange_basic2.phpt      3 Aug 2008 09:48:20 -0000
  200. @@ -0,0 +1,33 @@
  201. +--TEST--
  202. +ArrayObject::exchangeArray(object)
  203. +--FILE--
  204. +<?php
  205. +echo "--> exchangeArray(array):\n";
  206. +$ao = new ArrayObject();
  207. +$ao->exchangeArray(array('original'));
  208. +var_dump($ao);
  209. +
  210. +echo "\n--> exchangeArray(object):\n";
  211. +$obj = new stdClass;
  212. +$obj->newProp = 'changed';
  213. +$ao->exchangeArray($obj);
  214. +var_dump($ao);
  215. +?>
  216. +--EXPECTF--
  217. +--> exchangeArray(array):
  218. +object(ArrayObject)#%d (1) {
  219. ["storage":"ArrayObject":private]=>
  220. +  array(1) {
  221. +    [0]=>
  222. +    string(8) "original"
  223. }
  224. +}
  225. +
  226. +--> exchangeArray(object):
  227. +object(ArrayObject)#%d (1) {
  228. ["storage":"ArrayObject":private]=>
  229. +  object(stdClass)#%d (1) {
  230. +    ["newProp"]=>
  231. +    string(7) "changed"
  232. }
  233. +}
  234. \ No newline at end of file

Paste Details

advertising

Update the Post

Either update this post and resubmit it with changes, or make a new post.

You may also comment on this post.

update paste below
details of the post (optional)

Note: Only the paste content is required, though the following information can be useful to others.

Save name / title?

(space separated, optional)



Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.

worth-right
worth-right
fantasy-obligation