Commit:    42574690795937290a4ad6d319f917c077542953
Author:    Mark Baker <mba...@inviqa.com>         Mon, 18 Mar 2013 22:01:42 
+0100
Committer: David Soria Parra <d...@php.net>      Tue, 19 Mar 2013 14:46:21 +0100
Parents:   4837bdb91049e47e0c15873a2d1d4d1f7a4c65d2
Branches:  PHP-5.5 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=42574690795937290a4ad6d319f917c077542953

Log:
Fix #48358 add() method for SplDoublyLinkedLis

Bugs:
https://bugs.php.net/48358

Changed paths:
  M  NEWS
  M  ext/spl/spl_dllist.c
  A  ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt
  A  ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt
  A  ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt
  A  ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt
  A  ext/spl/tests/dllist_013.phpt

diff --git a/NEWS b/NEWS
index 2ea5117..805a40d 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,10 @@ PHP                                                          
              NEWS
     (Gustavo, Derick, Anatol)
   . Fixed bug #62852 (Unserialize Invalid Date causes crash). (Anatol)
 
+- SPL:
+  . Implement FR #48358 (Add SplDoublyLinkedList::add() to insert an element
+    at a given offset). (Mark Baker, David Soria Parra)
+
 07 Mar 2013, PHP 5.5.0 Alpha 6
 
 - Core:
diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c
index a7f15d0..3ac2201 100644
--- a/ext/spl/spl_dllist.c
+++ b/ext/spl/spl_dllist.c
@@ -794,7 +794,7 @@ SPL_METHOD(SplDoublyLinkedList, offsetGet)
        intern = (spl_dllist_object*)zend_object_store_get_object(getThis() 
TSRMLS_CC);
        index  = spl_offset_convert_to_long(zindex TSRMLS_CC);
 
-    if (index < 0 || index >= intern->llist->count) {
+       if (index < 0 || index >= intern->llist->count) {
                zend_throw_exception(spl_ce_OutOfRangeException, "Offset 
invalid or out of range", 0 TSRMLS_CC);
                return;
        }
@@ -881,9 +881,9 @@ SPL_METHOD(SplDoublyLinkedList, offsetUnset)
 
        intern = (spl_dllist_object*)zend_object_store_get_object(getThis() 
TSRMLS_CC);
        index  = spl_offset_convert_to_long(zindex TSRMLS_CC);
-    llist  = intern->llist;
+       llist  = intern->llist;
 
-    if (index < 0 || index >= intern->llist->count) {
+       if (index < 0 || index >= intern->llist->count) {
                zend_throw_exception(spl_ce_OutOfRangeException, "Offset out of 
range", 0 TSRMLS_CC);
                return;
        }
@@ -1138,7 +1138,7 @@ SPL_METHOD(SplDoublyLinkedList, serialize)
        spl_dllist_object     *intern   = 
(spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
        smart_str              buf      = {0};
        spl_ptr_llist_element *current  = intern->llist->head, *next;
-    zval                   *flags;
+       zval                   *flags;
        php_serialize_data_t   var_hash;
 
        if (zend_parse_parameters_none() == FAILURE) {
@@ -1234,6 +1234,61 @@ error:
 
 } /* }}} */
 
+/* {{{ proto void SplDoublyLinkedList::add(mixed $index, mixed $newval) U
+ Inserts a new entry before the specified $index consisting of $newval. */
+SPL_METHOD(SplDoublyLinkedList, add)
+{
+       zval                  *zindex, *value;
+       spl_dllist_object     *intern;
+       spl_ptr_llist_element *element;
+       long                  index;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zindex, 
&value) == FAILURE) {
+               return;
+       }
+       SEPARATE_ARG_IF_REF(value);
+
+       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() 
TSRMLS_CC);
+       index  = spl_offset_convert_to_long(zindex TSRMLS_CC);
+
+       if (index < 0 || index > intern->llist->count) {
+               zend_throw_exception(spl_ce_OutOfRangeException, "Offset 
invalid or out of range", 0 TSRMLS_CC);
+               return;
+       }
+
+       if (index == intern->llist->count) {
+               /* If index is the last entry+1 then we do a push because we're 
not inserting before any entry */
+               spl_ptr_llist_push(intern->llist, value TSRMLS_CC);
+       } else {
+               /* Get the element we want to insert before */
+               element = spl_ptr_llist_offset(intern->llist, index, 
intern->flags & SPL_DLLIST_IT_LIFO);
+
+               /* Create the new element we want to insert */
+               spl_ptr_llist_element *elem = 
emalloc(sizeof(spl_ptr_llist_element));
+
+               elem->data = value;
+               elem->rc   = 1;
+               /* connect to the neighbours */
+               elem->next = element;
+               elem->prev = element->prev;
+
+               /* connect the neighbours to this new element */
+               if (elem->prev == NULL) {
+                       intern->llist->head = elem;
+               } else {
+                       element->prev->next = elem;
+               }
+               element->prev = elem;
+
+               intern->llist->count++;
+
+               if (intern->llist->ctor) {
+                       intern->llist->ctor(elem TSRMLS_CC);
+               }
+       }
+} /* }}} */
+
+
 /* iterator handler table */
 zend_object_iterator_funcs spl_dllist_it_funcs = {
        spl_dllist_it_dtor,
@@ -1321,6 +1376,9 @@ static const zend_function_entry 
spl_funcs_SplDoublyLinkedList[] = {
        SPL_ME(SplDoublyLinkedList, offsetGet,       arginfo_dllist_offsetGet,  
     ZEND_ACC_PUBLIC)
        SPL_ME(SplDoublyLinkedList, offsetSet,       arginfo_dllist_offsetSet,  
     ZEND_ACC_PUBLIC)
        SPL_ME(SplDoublyLinkedList, offsetUnset,     arginfo_dllist_offsetGet,  
     ZEND_ACC_PUBLIC)
+
+       SPL_ME(SplDoublyLinkedList, add,             arginfo_dllist_offsetSet,  
     ZEND_ACC_PUBLIC)
+
        /* Iterator */
        SPL_ME(SplDoublyLinkedList, rewind,          arginfo_dllist_void,       
     ZEND_ACC_PUBLIC)
        SPL_ME(SplDoublyLinkedList, current,         arginfo_dllist_void,       
     ZEND_ACC_PUBLIC)
diff --git a/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt 
b/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt
new file mode 100644
index 0000000..b94b067
--- /dev/null
+++ b/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Check that SplDoublyLinkedList::add throws an exception with an invalid offset 
argument
+--FILE--
+<?php
+try {
+       $dll = new SplDoublyLinkedList();
+       var_dump($dll->add(12,'Offset 12 should not exist'));
+} catch (OutOfRangeException $e) {
+       echo "Exception: ".$e->getMessage()."\n";
+}
+?>
+--EXPECTF--
+Exception: Offset invalid or out of range
diff --git a/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt 
b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt
new file mode 100644
index 0000000..12cfe40
--- /dev/null
+++ b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Check that SplDoublyLinkedList::add generate a warning and returns a NULL with 
missing arguments
+--FILE--
+<?php
+$dll = new SplDoublyLinkedList();
+var_dump($dll->add());
+?>
+--EXPECTF--
+Warning: SplDoublyLinkedList::add() expects exactly 2 parameters, 0 given in 
%s on line %d
+NULL
+
diff --git a/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt 
b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt
new file mode 100644
index 0000000..c9c3193
--- /dev/null
+++ b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Check that SplDoublyLinkedList::add generate a warning and returns a NULL with 
a missing value argument
+--FILE--
+<?php
+$dll = new SplDoublyLinkedList();
+var_dump($dll->add(2));
+?>
+--EXPECTF--
+Warning: SplDoublyLinkedList::add() expects exactly 2 parameters, 1 given in 
%s on line %d
+NULL
+
diff --git a/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt 
b/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt
new file mode 100644
index 0000000..396f89b
--- /dev/null
+++ b/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Check that SplDoublyLinkedList::add throws an exception with an invalid offset 
argument
+--FILE--
+<?php
+try {
+       $dll = new SplDoublyLinkedList();
+       var_dump($dll->add(NULL,2));
+} catch (OutOfRangeException $e) {
+       echo "Exception: ".$e->getMessage()."\n";
+}
+?>
+--EXPECTF--
+Exception: Offset invalid or out of range
diff --git a/ext/spl/tests/dllist_013.phpt b/ext/spl/tests/dllist_013.phpt
new file mode 100644
index 0000000..b60f063
--- /dev/null
+++ b/ext/spl/tests/dllist_013.phpt
@@ -0,0 +1,45 @@
+--TEST--
+SPL: DoublyLinkedList: insert operations
+--FILE--
+<?php
+$dll = new SplDoublyLinkedList();
+// errors
+try {
+       $dll->add(2,5);
+} catch (OutOfRangeException $e) {
+       echo "Exception: ".$e->getMessage()."\n";
+}
+
+$dll->add(0,6);                                                //      6
+$dll->add(0,3);                                                //      3 6
+// Insert in the middle of the DLL
+$dll->add(1,4);                                                //      3 4 6
+$dll->add(2,5);                                                //      3 4 5 6
+$dll->unshift(2);                                      //      2 3 5 4 6
+// Insert at the beginning and end of the DLL
+$dll->add(0,1);                                                //      1 2 3 4 
5 6
+$dll->add(6,7);                                                //      1 2 3 4 
5 6 7
+
+echo count($dll)."\n";
+
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+Exception: Offset invalid or out of range
+7
+7
+6
+5
+4
+3
+2
+1
+===DONE===
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to