Changeset 274 for trunk

Show
Ignore:
Timestamp:
10/04/2007 17:04:54 (14 months ago)
Author:
indeyets
Message:

- added support for loading explicitly typed DateTime? (with timestamp-compatible value)
- fixed loading of maps with numeric keys
- added rudimentary support for loading ArrayAccess?-compatible classes (todo, todo, todo…)

Location:
trunk/ext/php
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/ext/php/CHANGELOG

    r273 r274  
    77    - gcc-2.95 compatibility (patch by Brian J. France) 
    88    - fixed dumping of mixed arrays and numeric-arrays starting from non-zero digit 
     9    - added support for loading explicitly typed DateTime (with timestamp-compatible value) 
     10    - fixed loading of maps with numeric keys 
    911 
    1012- version: 0.9.1 
  • trunk/ext/php/TODO

    r268 r274  
    1010    - "!php/hash:YAML::ClassName" 
    1111    - "!php/array:YAML::ClassName" 
    12     - "!php:YAML::Datetime" 
    1312    - "!php:YAML::ClassName (?)" 
     13  - allow user to assign custom handler for loading any other type of objects (java, ruby, etc.) 
    1414dump: 
    1515  - merge 
  • trunk/ext/php/phpext.c

    r273 r274  
    360360                        } else if (strcmp(n->type_id, "float#neginf") == 0) { 
    361361                                ZVAL_DOUBLE(o, -inf()); 
    362                         } else if (strncmp(n->type_id, "timestamp", 9) == 0) { 
     362                        } else if (strncmp(n->type_id, "timestamp", 9) == 0 || strcmp(n->type_id, "php:YAML::Datetime") == 0) { 
    363363                                zval fname, param, *params[1]; 
    364364                                TSRMLS_FETCH(); 
     
    381381                case syck_seq_kind: 
    382382                { 
    383                         size_t i; 
    384  
    385                         array_init(o); 
    386  
    387                         for (i = 0; i < n->data.list->idx; i++) { 
    388                                 SYMID oid = syck_seq_read(n, i); 
    389                                 zval *o2; 
    390  
    391                                 syck_lookup_sym(p, oid, (char **) &o2); /* retrieving child-node */ 
    392  
    393                                 add_index_zval(o, i, o2); 
     383                        if (NULL == n->type_id || strcmp(n->type_id, "php/array") == 0) { 
     384                                size_t i; 
     385 
     386                                /* Just an array */ 
     387                                array_init(o); 
     388 
     389                                for (i = 0; i < n->data.list->idx; i++) { 
     390                                        SYMID oid = syck_seq_read(n, i); 
     391                                        zval *o2; 
     392 
     393                                        syck_lookup_sym(p, oid, (char **) &o2); /* retrieving child-node */ 
     394 
     395                                        add_index_zval(o, i, o2); 
     396                                } 
     397                        } else if (strncmp(n->type_id, "php/array:", 10) == 0) { 
     398                                /* some classm which implements ArrayAccess */ 
     399                                size_t classname_len = strlen(n->type_id) - 10; 
     400                                char *classname = emalloc(classname_len + 1); 
     401                                zend_class_entry **ce; 
     402                                TSRMLS_FETCH(); 
     403 
     404                                strncpy(classname, n->type_id + 10, classname_len + 1); 
     405 
     406                                if (FAILURE == zend_lookup_class_ex(classname, classname_len, 1, &ce TSRMLS_CC)) { 
     407                                        zend_throw_exception_ex(syck_exception_entry, 0 TSRMLS_CC, "Couldn't find %s class on line %d, col %d: '%s'", classname, p->linect, p->cursor - p->lineptr, p->lineptr); 
     408                                        efree(classname); 
     409                                        break; 
     410                                } 
     411 
     412                                if (0 == instanceof_function_ex(*ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) { 
     413                                        zend_throw_exception_ex(syck_exception_entry, 0 TSRMLS_CC, "Class %s doesn't implement ArrayAccess on line %d, col %d: '%s'", classname, p->linect, p->cursor - p->lineptr, p->lineptr); 
     414                                        efree(classname); 
     415                                        break; 
     416                                } 
     417 
     418                                /* 
     419                                 * TODO: add filling of ArrayAccess object with values 
     420                                 */ 
     421                                array_init(o); 
     422 
     423                                efree(classname); 
     424                        } else { 
     425                                /* something else */ 
     426                                php_error(E_NOTICE, "syck extension didn't handle %s type", n->type_id); 
    394427                        } 
    395428                } 
     
    398431                case syck_map_kind: 
    399432                { 
    400                         SYMID oid; 
    401                         size_t i; 
    402                         zval *o2, *o3; 
    403                         zval *res; 
    404  
    405                         array_init(o); 
    406  
    407                         for (i = 0; i < n->data.pairs->idx; i++) { 
    408                                 oid = syck_map_read(n, map_key, i); 
    409                                 syck_lookup_sym(p, oid, (char **) &o2); /* retrieving key-node */ 
    410  
    411                                 if (o2->type == IS_STRING) { 
    412                                         oid = syck_map_read(n, map_value, i); 
    413                                         syck_lookup_sym(p, oid, (char **) &o3); /* retrieving value-node */ 
    414  
    415                                         add_assoc_zval(o, o2->value.str.val, o3); 
    416                                 } 
    417  
    418                                 zval_ptr_dtor(&o2); 
     433                        if (NULL == n->type_id || strcmp(n->type_id, "php/hash") == 0) { 
     434                                SYMID oid; 
     435                                size_t i; 
     436                                zval *o2, *o3; 
     437                                zval *res; 
     438 
     439                                array_init(o); 
     440 
     441                                for (i = 0; i < n->data.pairs->idx; i++) { 
     442                                        oid = syck_map_read(n, map_key, i); 
     443                                        syck_lookup_sym(p, oid, (char **) &o2); /* retrieving key-node */ 
     444 
     445                                        if (o2->type == IS_STRING || o2->type == IS_LONG) { 
     446                                                oid = syck_map_read(n, map_value, i); 
     447                                                syck_lookup_sym(p, oid, (char **) &o3); /* retrieving value-node */ 
     448 
     449                                                if (o2->type == IS_LONG) { 
     450                                                        add_index_zval(o, Z_LVAL_P(o2), o3); 
     451                                                } else { 
     452                                                        add_assoc_zval(o, Z_STRVAL_P(o2), o3); 
     453                                                } 
     454                                        } 
     455 
     456                                        zval_ptr_dtor(&o2); 
     457                                } 
     458                        } else if (strncmp(n->type_id, "php/hash:", 9) == 0) { 
     459                                /* some classm which implements ArrayAccess */ 
     460                                size_t classname_len = strlen(n->type_id) - 9; 
     461                                char *classname = emalloc(classname_len + 1); 
     462                                zend_class_entry **ce; 
     463                                TSRMLS_FETCH(); 
     464 
     465                                strncpy(classname, n->type_id + 9, classname_len + 1); 
     466 
     467                                if (FAILURE == zend_lookup_class_ex(classname, classname_len, 1, &ce TSRMLS_CC)) { 
     468                                        zend_throw_exception_ex(syck_exception_entry, 0 TSRMLS_CC, "Couldn't find %s class on line %d, col %d: '%s'", classname, p->linect, p->cursor - p->lineptr, p->lineptr); 
     469                                        efree(classname); 
     470                                        break; 
     471                                } 
     472 
     473                                if (0 == instanceof_function_ex(*ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) { 
     474                                        zend_throw_exception_ex(syck_exception_entry, 0 TSRMLS_CC, "Class %s doesn't implement ArrayAccess on line %d, col %d: '%s'", classname, p->linect, p->cursor - p->lineptr, p->lineptr); 
     475                                        efree(classname); 
     476                                        break; 
     477                                } 
     478 
     479                                /* 
     480                                 * TODO: add filling of ArrayAccess object with values 
     481                                 */ 
     482                                array_init(o); 
     483 
     484                                efree(classname); 
     485                        } else { 
     486                                /* something else */ 
     487                                php_error(E_NOTICE, "syck extension didn't handle %s type", n->type_id); 
    419488                        } 
    420489                } 
  • trunk/ext/php/phpunit-tests/TestLoad.php

    r268 r274  
    77 
    88error_reporting(E_ALL); 
     9 
     10class SyckTestSomeClass {} 
     11 
    912 
    1013class TestLoad extends PHPUnit_Framework_TestCase 
     
    136139        // date 
    137140        $this->assertType('DateTime', syck_load("2002-12-14")); 
     141 
     142        // explicit 
     143        $this->assertType('DateTime', syck_load("!php:YAML::Datetime 2002-12-14")); 
     144    } 
     145 
     146    public function testArray() 
     147    { 
     148        $this->assertEquals(syck_load('[]'), array()); 
     149        $this->assertEquals(syck_load('[a, b, c]'), array('a', 'b', 'c')); 
     150        $this->assertEquals(syck_load('!php/array []'), array()); 
     151 
     152        // ArrayObject implements ArrayAccess: OK 
     153        $this->assertEquals(syck_load('!php/array:ArrayObject []'), array()); 
     154 
     155        // SyckTestSomeClass doesn't implement ArrayAccess: FAILURE 
     156        try { 
     157            syck_load('!php/array:SyckTestSomeClass []'); 
     158            $this->assertTrue(false); 
     159        } catch (SyckException $e) { 
     160            $this->assertTrue(true); 
     161        } 
     162 
     163        // SyckTestOtherClass doesn't exist: FAILURE 
     164        try { 
     165            syck_load('!php/array:SyckTestOtherClass []'); 
     166            $this->assertTrue(false); 
     167        } catch (SyckException $e) { 
     168            $this->assertTrue(true); 
     169        } 
     170    } 
     171 
     172    public function testHash() 
     173    { 
     174        $this->assertEquals(syck_load('{}'), array()); 
     175        $this->assertEquals(syck_load('{0: a, 1: b, 2: c}'), array('a', 'b', 'c')); 
     176 
     177        // ArrayObject implements ArrayAccess: OK 
     178        $this->assertEquals(syck_load('!php/hash:ArrayObject {}'), array()); 
     179 
     180        // SyckTestSomeClass doesn't implement ArrayAccess: FAILURE 
     181        try { 
     182            syck_load('!php/hash:SyckTestSomeClass {}'); 
     183            $this->assertTrue(false); 
     184        } catch (SyckException $e) { 
     185            $this->assertTrue(true); 
     186        } 
     187 
     188        // SyckTestOtherClass doesn't exist: FAILURE 
     189        try { 
     190            syck_load('!php/hash:SyckTestOtherClass {}'); 
     191            $this->assertTrue(false); 
     192        } catch (SyckException $e) { 
     193            $this->assertTrue(true); 
     194        } 
    138195    } 
    139196}