FAQ
Please take under consideration this patch to fully utilize cast_object
handlers in the new parameter parsing API.

The old parameter API forced the called function to validate and convert its
arguments using the convert_to_* functions.
The convert_to_* functions make use of cast_object handlers if they exist on
objects which makes passing objects (which implement cast_object) to these
functions possible.

However, with the new parameter parsing API (zend_parse_parameters, et.al.),
it only makes use of the cast_object handler if the expected type is a
string.
This unnecessarily weakens the capability of the cast_object handler.
It makes sense that if an object implements a handler for a string cast,
then it should be able to be used anywhere a string can.

The patch is also attached as a .txt file in case the email really hoses it.


--- zend_API.c 2005-11-03 20:26:02.000000000 -0800
+++ zend_API.c 2005-11-03 20:26:02.000000000 -0800
@@ -312,8 +312,17 @@
*p = Z_LVAL_PP(arg);
break;

+ case IS_OBJECT: {
+ if (Z_OBJ_HANDLER_PP(arg,
cast_object)) {
+
SEPARATE_ZVAL_IF_NOT_REF(arg);
+ if
(Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_LONG, 0 TSRMLS_CC) ==
SUCCESS) {
+ *p =
Z_LVAL_PP(arg);
+ break;
+ }
+ }
+ }
+
case IS_ARRAY:
- case IS_OBJECT:
case IS_RESOURCE:
default:
return "long";
@@ -346,8 +355,17 @@
*p = Z_DVAL_PP(arg);
break;

+ case IS_OBJECT: {
+ if (Z_OBJ_HANDLER_PP(arg,
cast_object)) {
+
SEPARATE_ZVAL_IF_NOT_REF(arg);
+ if
(Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_DOUBLE, 0 TSRMLS_CC) ==
SUCCESS) {
+ *p =
Z_DVAL_PP(arg);
+ break;
+ }
+ }
+ }
+
case IS_ARRAY:
- case IS_OBJECT:
case IS_RESOURCE:
default:
return "double";
@@ -408,8 +426,17 @@
*p = Z_BVAL_PP(arg);
break;

+ case IS_OBJECT: {
+ if (Z_OBJ_HANDLER_PP(arg,
cast_object)) {
+
SEPARATE_ZVAL_IF_NOT_REF(arg);
+ if
(Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_BOOL, 0 TSRMLS_CC) ==
SUCCESS) {
+ *p =
Z_BVAL_PP(arg);
+ break;
+ }
+ }
+ }
+
case IS_ARRAY:
- case IS_OBJECT:
case IS_RESOURCE:
default:
return "boolean";
@@ -434,6 +461,15 @@
case 'a':
{
zval **p = va_arg(*va, zval **);
+ if (Z_TYPE_PP(arg) == IS_OBJECT) {
+ if (Z_OBJ_HANDLER_PP(arg,
cast_object)) {
+
SEPARATE_ZVAL_IF_NOT_REF(arg);
+ if (Z_OBJ_HANDLER_PP(arg,
cast_object)(*arg, *arg, IS_ARRAY, 0 TSRMLS_CC) == SUCCESS) {
+ *p = *arg;
+ break;
+ }
+ }
+ }
if (Z_TYPE_PP(arg) != IS_ARRAY) {
if (Z_TYPE_PP(arg) == IS_NULL &&
return_null) {
*p = NULL;

Search Discussions

  • Marcus Boerger at Nov 4, 2005 at 8:28 am
    Hello Bob,

    this is a) wrong in the way you call the cast handler and b) we will
    definitively not add this behavior before the next major release aka
    HEAD. However it would be better to call the conversion functions
    (zend_operators.h) here to have get handler used when no cast handler
    is available to avoid inconsistencies with auto conversions in other
    places. I guess I know where you're heading, i am not quite sure this
    is essantial or even the rigth thing to for PHP yet at least for stuff
    like the array functions and objects that overload ArrayAccess it is
    more than usefull.

    regards
    marcus

    p.s.: You still haven't shown me any of your extension code :-/

    Friday, November 4, 2005, 9:06:27 AM, you wrote:
    --- zend_API.c 2005-11-03 20:26:02.000000000 -0800
    +++ zend_API.c 2005-11-03 20:26:02.000000000 -0800
    @@ -312,8 +312,17 @@
    *p = Z_LVAL_PP(arg);
    break;
    + case IS_OBJECT: {
    + if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
    + SEPARATE_ZVAL_IF_NOT_REF(arg);
    + if
    (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_LONG, 0 TSRMLS_CC) == SUCCESS) {
    + *p = Z_LVAL_PP(arg);
    + break;
    + }
    + }
    + }
    +
    case IS_ARRAY:
    - case IS_OBJECT:
    case IS_RESOURCE:
    default:
    return "long";
    @@ -346,8 +355,17 @@
    *p = Z_DVAL_PP(arg);
    break;
    + case IS_OBJECT: {
    + if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
    + SEPARATE_ZVAL_IF_NOT_REF(arg);
    + if
    (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_DOUBLE, 0 TSRMLS_CC) == SUCCESS) {
    + *p = Z_DVAL_PP(arg);
    + break;
    + }
    + }
    + }
    +
    case IS_ARRAY:
    - case IS_OBJECT:
    case IS_RESOURCE:
    default:
    return "double";
    @@ -408,8 +426,17 @@
    *p = Z_BVAL_PP(arg);
    break;
    + case IS_OBJECT: {
    + if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
    + SEPARATE_ZVAL_IF_NOT_REF(arg);
    + if
    (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_BOOL, 0 TSRMLS_CC) == SUCCESS) {
    + *p = Z_BVAL_PP(arg);
    + break;
    + }
    + }
    + }
    +
    case IS_ARRAY:
    - case IS_OBJECT:
    case IS_RESOURCE:
    default:
    return "boolean";
    @@ -434,6 +461,15 @@
    case 'a':
    {
    zval **p = va_arg(*va, zval **);
    + if (Z_TYPE_PP(arg) == IS_OBJECT) {
    + if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
    + SEPARATE_ZVAL_IF_NOT_REF(arg);
    + if (Z_OBJ_HANDLER_PP(arg,
    cast_object)(*arg, *arg, IS_ARRAY, 0 TSRMLS_CC) == SUCCESS) {
    + *p = *arg;
    + break;
    + }
    + }
    + }
    if (Z_TYPE_PP(arg) != IS_ARRAY) {
    if (Z_TYPE_PP(arg) == IS_NULL && return_null) {
    *p = NULL;



    Best regards,
    Marcus
  • Bob Silva at Nov 4, 2005 at 10:17 am
    Hi Marcus,

    OK, I got my learning cap on, why is it the wrong way to call cast_object? I
    just copied it from the example for a string param and it worked so I am
    curious why it is wrong. I agree the convert_to_* functions are a better
    solution for the reasons you mentioned, again, I just followed the example
    for the string case.

    I guess I don't see what this modification has to do with the future of PHP
    though. Why restrict the parameter API to objects that can only convert to a
    string value? I'd say the current behavior is almost worthy of a bug.


    Imagine we have a class that represents a String and supports the
    cast_object handler for all base types. We'll name it ZString.

    The following code works fine: (Ignore the fact that I should be using an
    integer, not a string equivalent)

    $str = new ZString('PHP Object Wrappers');
    $start = new ZString('4');
    $length = new ZString('6');

    echo substr($str, $start, $length);

    Result: Object

    however, this will fail:

    echo wordwrap($str, $length);

    Result: Warning: wordwrap() expects parameter 2 to be long

    The only difference is the method it uses to get its parameters.

    substr() uses zend_get_parameters_ex and wordwrap() uses
    zend_parse_parameters

    I can work around this restriction by pulling in my parameters as zvals and
    doing my own conversion, but IMHO, the engine really should handle it using
    the built-in capabilities that already exist and aren't being used.

    In regards to the extension, I have the base objects complete: ZArray,
    ZChar, ZBoolean, ZDouble, ZInt, ZString. They all work interchangeably (for
    the most part) with their PHP native counterparts as long as you aren't
    using them on the left side of an expression.

    $a = new ZString('PHP ');
    $b = new ZString('Object ');
    $c = new ZString('Wrappers');

    echo $a.$b.$c; (no reliance on __toString, so concatenation is possible)
    PHP Object Wrappers

    $int = new ZInt(5);
    echo $int + 5;
    10

    They make extended use of the ArrayAccess interface to implement properties
    and indexers.

    $a = new ZString('PHP');
    echo $a['Length']; 3
    echo $a[0]; P
    echo $a['Chars']{1}; H
    echo $a->offsetGet(2); P

    Properties are also supported for derived user classes by defining
    accessors.

    class MyClass extends ZObject
    {
    function setMyProp($value)
    {
    if ($value is valid)
    $this->_props['MyProp'] = $value;
    }
    function getMyProp()
    {
    return $this->_props['MyProp'];
    }

    }

    $e = new MyClass;
    $e['MyProp'] = 'PHP Object Wrappers';
    echo $e['MyProp'];


    Where appropriate, they implement Iterator or IteratorAggregate with C# type
    wrappers.
    foreach ($a as $c)
    echo $c;

    PHP

    $enum = $a->GetEnumerator();
    while ($enum->MoveNext())
    echo $enum->GetCurrent();

    PHP


    Its also completely exception based, no PHP errors surface during runtime.
    As you can tell, I am using C# as my model for the objects. They actually
    flow pretty well in a real application as well. One last addition that would
    be cool but likely to never happen in the PHP distro is the following:

    $a = "some string";
    $a->Substring(5,1);

    $b = 5;
    $b->Equals(3); (false)
    $b++;
    $b->Equals(6); (true)
    echo gettype($b); "object"

    Implicit conversion via cast handlers.


    I still have a couple weeks of work left on them. This is my first dabble in
    C so I have a lot of cleanup to do as well as learn how to turn it into a
    PECL extension.

    Why program if you can't have fun doing it?

    Bob


    -----Original Message-----
    From: Marcus Boerger
    Sent: Friday, November 04, 2005 12:29 AM
    To: Bob Silva
    Cc: internals@lists.php.net
    Subject: Re: [PHP-DEV] [PATCH] - Standardize argument parsing of objects

    Hello Bob,

    this is a) wrong in the way you call the cast handler and b) we will
    definitively not add this behavior before the next major release aka
    HEAD. However it would be better to call the conversion functions
    (zend_operators.h) here to have get handler used when no cast handler
    is available to avoid inconsistencies with auto conversions in other
    places. I guess I know where you're heading, i am not quite sure this
    is essantial or even the rigth thing to for PHP yet at least for stuff
    like the array functions and objects that overload ArrayAccess it is
    more than usefull.

    regards
    marcus

    p.s.: You still haven't shown me any of your extension code :-/

    Friday, November 4, 2005, 9:06:27 AM, you wrote:
    --- zend_API.c 2005-11-03 20:26:02.000000000 -0800
    +++ zend_API.c 2005-11-03 20:26:02.000000000 -0800
    @@ -312,8 +312,17 @@
    *p = Z_LVAL_PP(arg);
    break;
    + case IS_OBJECT: {
    + if
    (Z_OBJ_HANDLER_PP(arg, cast_object)) {
    +
    SEPARATE_ZVAL_IF_NOT_REF(arg);
    + if
    (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_LONG, 0 TSRMLS_CC) ==
    SUCCESS) {
    + *p =
    Z_LVAL_PP(arg);
    + break;
    + }
    + }
    + }
    +
    case IS_ARRAY:
    - case IS_OBJECT:
    case IS_RESOURCE:
    default:
    return "long";
    @@ -346,8 +355,17 @@
    *p = Z_DVAL_PP(arg);
    break;
    + case IS_OBJECT: {
    + if
    (Z_OBJ_HANDLER_PP(arg, cast_object)) {
    +
    SEPARATE_ZVAL_IF_NOT_REF(arg);
    + if
    (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_DOUBLE, 0 TSRMLS_CC)
    == SUCCESS) {
    + *p =
    Z_DVAL_PP(arg);
    + break;
    + }
    + }
    + }
    +
    case IS_ARRAY:
    - case IS_OBJECT:
    case IS_RESOURCE:
    default:
    return "double";
    @@ -408,8 +426,17 @@
    *p = Z_BVAL_PP(arg);
    break;
    + case IS_OBJECT: {
    + if
    (Z_OBJ_HANDLER_PP(arg, cast_object)) {
    +
    SEPARATE_ZVAL_IF_NOT_REF(arg);
    + if
    (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_BOOL, 0 TSRMLS_CC) ==
    SUCCESS) {
    + *p =
    Z_BVAL_PP(arg);
    + break;
    + }
    + }
    + }
    +
    case IS_ARRAY:
    - case IS_OBJECT:
    case IS_RESOURCE:
    default:
    return "boolean";
    @@ -434,6 +461,15 @@
    case 'a':
    {
    zval **p = va_arg(*va, zval **);
    + if (Z_TYPE_PP(arg) == IS_OBJECT) {
    + if (Z_OBJ_HANDLER_PP(arg,
    cast_object)) {
    +
    SEPARATE_ZVAL_IF_NOT_REF(arg);
    + if
    (Z_OBJ_HANDLER_PP(arg,
    cast_object)(*arg, *arg, IS_ARRAY, 0 TSRMLS_CC) == SUCCESS) {
    + *p = *arg;
    + break;
    + }
    + }
    + }
    if (Z_TYPE_PP(arg) != IS_ARRAY) {
    if (Z_TYPE_PP(arg) == IS_NULL &&
    return_null) {
    *p = NULL;



    Best regards,
    Marcus
  • Marcus Boerger at Nov 4, 2005 at 6:58 pm
    Hello Bob,

    Friday, November 4, 2005, 11:19:23 AM, you wrote:
    Hi Marcus,
    OK, I got my learning cap on, why is it the wrong way to call cast_object? I
    just copied it from the example for a string param and it worked so I am
    curious why it is wrong. I agree the convert_to_* functions are a better
    solution for the reasons you mentioned, again, I just followed the example
    for the string case.
    I guess I don't see what this modification has to do with the future of PHP
    though. Why restrict the parameter API to objects that can only convert to a
    string value? I'd say the current behavior is almost worthy of a bug. [...]
    In regards to the extension, I have the base objects complete: ZArray,
    ZChar, ZBoolean, ZDouble, ZInt, ZString. They all work interchangeably (for
    the most part) with their PHP native counterparts as long as you aren't
    using them on the left side of an expression.
    And that is where get/set handlers come into play and why calling cat
    handler alone is incorrect. Apart from that the 5 api has the parameter
    should_free which should be non null if read and write zval are the same
    so that the handler knows it must call zval_dtor on the readval prior to
    assigning the new value. Since this interface is borked it has changed
    in head. There read and write zval must be different and the caller has
    to take care about any required free/destruction. That you had a look
    into the stuff and haven't come accross this is again proof that the
    old api was not only bork but also used wrong.

    Best regards,
    Marcus
  • Bob Silva at Nov 5, 2005 at 2:10 am
    Hi Marcus,

    I think I understand what you are saying. I've added get and set handlers to
    my objects and can now achieve this:

    $a = new ZInt(5);
    $a += 1;
    echo ($a->Equals(6)) ? 'true':'false';

    =true

    as well as:

    $a = new ZChar('A');
    $a++;
    echo ($a->Equals('B')) ? 'true':'false';

    =true

    Thanks for helping me understand this. An unexpected side-effect is that by
    declaring my objects ahead of time like a typed language, I can use natives
    in an object context which is what I was looking to achieve. I still have a
    lot of testing to do though.

    $a = new ZString('PHP');
    $a .= ' Object Wrappers';
    echo $a->ToString();

    =PHP Object Wrappers

    My ZString objects are immutable, $a is actually a new ZString object after
    the concatenation.

    The parameter API (even in HEAD) is still a stumbling block though since it
    only converts objects for "syuTt" specifiers and not the others ("l", "b",
    "d" and preferably "a" which doesn't look possible without breaking BC since
    it relies on the get_properties handler first and convert_object_to_type
    second).

    Of course any good language provides a work around: (casting ahead of time)

    echo wordwrap(new ZString('PHP is cool'), (int)new ZInt(3));
    =PHP
    is
    cool


    I really don't know if this will be useful for anyone else but it sure is
    fun programming it and I'm learning a lot. People that are looking for a
    strongly typed PHP may find it useful once I complete the rest of the object
    framework. Next up is Collections. Again, I really appreciate you taking the
    time to reply to my questions and point me in the right direction.

    Bob



    -----Original Message-----
    From: Marcus Boerger
    Sent: Friday, November 04, 2005 10:59 AM
    To: Bob Silva
    Cc: internals@lists.php.net
    Subject: Re: [PHP-DEV] [PATCH] - Standardize argument parsing of objects

    Hello Bob,

    Friday, November 4, 2005, 11:19:23 AM, you wrote:
    Hi Marcus,
    OK, I got my learning cap on, why is it the wrong way to call
    cast_object? I
    just copied it from the example for a string param and it worked so I am
    curious why it is wrong. I agree the convert_to_* functions are a better
    solution for the reasons you mentioned, again, I just followed the example
    for the string case.
    I guess I don't see what this modification has to do with the future of PHP
    though. Why restrict the parameter API to objects that can only convert to a
    string value? I'd say the current behavior is almost worthy of a bug. [...]
    In regards to the extension, I have the base objects complete: ZArray,
    ZChar, ZBoolean, ZDouble, ZInt, ZString. They all work interchangeably (for
    the most part) with their PHP native counterparts as long as you aren't
    using them on the left side of an expression.
    And that is where get/set handlers come into play and why calling cat
    handler alone is incorrect. Apart from that the 5 api has the parameter
    should_free which should be non null if read and write zval are the same
    so that the handler knows it must call zval_dtor on the readval prior to
    assigning the new value. Since this interface is borked it has changed
    in head. There read and write zval must be different and the caller has
    to take care about any required free/destruction. That you had a look
    into the stuff and haven't come accross this is again proof that the
    old api was not only bork but also used wrong.

    Best regards,
    Marcus

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Jessie Hernandez at Nov 5, 2005 at 5:34 am
    Hi Bob,

    BTW, several months back I started working on a similar String class (you
    can see my post at http://news.php.net/php.pecl.dev/2512). It was meant as
    an OOP interface to all of the string-handling functions, and also had
    smart buffer management for speed. I started working on this hoping to have
    it be a part of the core, but at the time I was presented with several
    objections (most of them were because of the generic name chosen, "String",
    and because no one wanted it in the core, only on PECL). Even then, I was
    advised to wait for the Unicode changes to be merged before I continued
    (don't know if the Unicode work is done yet).

    I stopped working on this extension shortly thereafter and started working
    on the namespace patch (which is really more important anyways). I can post
    what I had done at the time if you want to take a look at it (I think I
    left the code at work, so it would have to wait till Monday).

    (IMHO, I still think a core String class would be very useful. There are
    many extensions that provide both a procedural and OOP interface. Take for
    example SQLite. You can either use the sqlite_* functions or use the
    SQLiteDatabase class. I don't see why strings should be any different.)


    Regards,

    Jessie


    Bob Silva wrote:
    Hi Marcus,

    I think I understand what you are saying. I've added get and set handlers
    to my objects and can now achieve this:

    $a = new ZInt(5);
    $a += 1;
    echo ($a->Equals(6)) ? 'true':'false';

    =true

    as well as:

    $a = new ZChar('A');
    $a++;
    echo ($a->Equals('B')) ? 'true':'false';

    =true

    Thanks for helping me understand this. An unexpected side-effect is that
    by declaring my objects ahead of time like a typed language, I can use
    natives in an object context which is what I was looking to achieve. I
    still have a lot of testing to do though.

    $a = new ZString('PHP');
    $a .= ' Object Wrappers';
    echo $a->ToString();

    =PHP Object Wrappers

    My ZString objects are immutable, $a is actually a new ZString object
    after the concatenation.

    The parameter API (even in HEAD) is still a stumbling block though since
    it only converts objects for "syuTt" specifiers and not the others ("l",
    "b", "d" and preferably "a" which doesn't look possible without breaking
    BC since it relies on the get_properties handler first and
    convert_object_to_type second).

    Of course any good language provides a work around: (casting ahead of
    time)

    echo wordwrap(new ZString('PHP is cool'), (int)new ZInt(3));
    =PHP
    is
    cool


    I really don't know if this will be useful for anyone else but it sure is
    fun programming it and I'm learning a lot. People that are looking for a
    strongly typed PHP may find it useful once I complete the rest of the
    object framework. Next up is Collections. Again, I really appreciate you
    taking the time to reply to my questions and point me in the right
    direction.

    Bob



    -----Original Message-----
    From: Marcus Boerger
    Sent: Friday, November 04, 2005 10:59 AM
    To: Bob Silva
    Cc: internals@lists.php.net
    Subject: Re: [PHP-DEV] [PATCH] - Standardize argument parsing of objects

    Hello Bob,

    Friday, November 4, 2005, 11:19:23 AM, you wrote:
    Hi Marcus,
    OK, I got my learning cap on, why is it the wrong way to call
    cast_object? I
    just copied it from the example for a string param and it worked so I
    am curious why it is wrong. I agree the convert_to_* functions are a
    better solution for the reasons you mentioned, again, I just followed
    the example
    for the string case.
    I guess I don't see what this modification has to do with the future of PHP
    though. Why restrict the parameter API to objects that can only convert to a
    string value? I'd say the current behavior is almost worthy of a bug. [...]
    In regards to the extension, I have the base objects complete: ZArray,
    ZChar, ZBoolean, ZDouble, ZInt, ZString. They all work interchangeably (for
    the most part) with their PHP native counterparts as long as you aren't
    using them on the left side of an expression.
    And that is where get/set handlers come into play and why calling cat
    handler alone is incorrect. Apart from that the 5 api has the parameter
    should_free which should be non null if read and write zval are the same
    so that the handler knows it must call zval_dtor on the readval prior to
    assigning the new value. Since this interface is borked it has changed
    in head. There read and write zval must be different and the caller has
    to take care about any required free/destruction. That you had a look
    into the stuff and haven't come accross this is again proof that the
    old api was not only bork but also used wrong.

    Best regards,
    Marcus

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Bob Silva at Nov 5, 2005 at 6:48 am
    Hi Jessie,

    I'd be more than happy to get some examples of how others would implement a
    string class. I am doing most of my modeling after the .NET 2.0 framework
    for my objects. I find it to be a well organized and capable framework,
    especially the new ASP.NET 2.0 features like the Role Manager. It also saves
    on my documentation, just go look at msdn2.microsoft.com. :) kidding

    I started this just for fun and an introduction to C, but I am planning on
    putting into PECL when it is stable, which is quite far off for the whole
    framework. Should be ready in time for PHP6.

    I was just reading all the Unicode docs tonight preparing to start my
    conversion to support it. Gets quite messy pretty fast.

    Any word on whether the core team is going to accept the namespace patch? It
    will be beneficial to my development as well for obvious reasons.

    Bob


    -----Original Message-----
    From: Jessie Hernandez
    Sent: Friday, November 04, 2005 9:35 PM
    To: internals@lists.php.net
    Subject: RE: [PHP-DEV] [PATCH] - Standardize argument parsing of objects

    Hi Bob,

    BTW, several months back I started working on a similar String class (you
    can see my post at http://news.php.net/php.pecl.dev/2512). It was meant as
    an OOP interface to all of the string-handling functions, and also had
    smart buffer management for speed. I started working on this hoping to
    have
    it be a part of the core, but at the time I was presented with several
    objections (most of them were because of the generic name chosen,
    "String",
    and because no one wanted it in the core, only on PECL). Even then, I was
    advised to wait for the Unicode changes to be merged before I continued
    (don't know if the Unicode work is done yet).

    I stopped working on this extension shortly thereafter and started working
    on the namespace patch (which is really more important anyways). I can
    post
    what I had done at the time if you want to take a look at it (I think I
    left the code at work, so it would have to wait till Monday).

    (IMHO, I still think a core String class would be very useful. There are
    many extensions that provide both a procedural and OOP interface. Take for
    example SQLite. You can either use the sqlite_* functions or use the
    SQLiteDatabase class. I don't see why strings should be any different.)


    Regards,

    Jessie


    Bob Silva wrote:
    Hi Marcus,

    I think I understand what you are saying. I've added get and set handlers
    to my objects and can now achieve this:

    $a = new ZInt(5);
    $a += 1;
    echo ($a->Equals(6)) ? 'true':'false';

    =true

    as well as:

    $a = new ZChar('A');
    $a++;
    echo ($a->Equals('B')) ? 'true':'false';

    =true

    Thanks for helping me understand this. An unexpected side-effect is that
    by declaring my objects ahead of time like a typed language, I can use
    natives in an object context which is what I was looking to achieve. I
    still have a lot of testing to do though.

    $a = new ZString('PHP');
    $a .= ' Object Wrappers';
    echo $a->ToString();

    =PHP Object Wrappers

    My ZString objects are immutable, $a is actually a new ZString object
    after the concatenation.

    The parameter API (even in HEAD) is still a stumbling block though since
    it only converts objects for "syuTt" specifiers and not the others ("l",
    "b", "d" and preferably "a" which doesn't look possible without breaking
    BC since it relies on the get_properties handler first and
    convert_object_to_type second).

    Of course any good language provides a work around: (casting ahead of
    time)

    echo wordwrap(new ZString('PHP is cool'), (int)new ZInt(3));
    =PHP
    is
    cool


    I really don't know if this will be useful for anyone else but it sure is
    fun programming it and I'm learning a lot. People that are looking for a
    strongly typed PHP may find it useful once I complete the rest of the
    object framework. Next up is Collections. Again, I really appreciate you
    taking the time to reply to my questions and point me in the right
    direction.

    Bob



    -----Original Message-----
    From: Marcus Boerger
    Sent: Friday, November 04, 2005 10:59 AM
    To: Bob Silva
    Cc: internals@lists.php.net
    Subject: Re: [PHP-DEV] [PATCH] - Standardize argument parsing of
    objects
    Hello Bob,

    Friday, November 4, 2005, 11:19:23 AM, you wrote:
    Hi Marcus,
    OK, I got my learning cap on, why is it the wrong way to call
    cast_object? I
    just copied it from the example for a string param and it worked so I
    am curious why it is wrong. I agree the convert_to_* functions are a
    better solution for the reasons you mentioned, again, I just followed
    the example
    for the string case.
    I guess I don't see what this modification has to do with the future
    of
    PHP
    though. Why restrict the parameter API to objects that can only
    convert
    to a
    string value? I'd say the current behavior is almost worthy of a bug. [...]
    In regards to the extension, I have the base objects complete:
    ZArray,
    ZChar, ZBoolean, ZDouble, ZInt, ZString. They all work
    interchangeably
    (for
    the most part) with their PHP native counterparts as long as you
    aren't
    using them on the left side of an expression.
    And that is where get/set handlers come into play and why calling cat
    handler alone is incorrect. Apart from that the 5 api has the parameter
    should_free which should be non null if read and write zval are the
    same
    so that the handler knows it must call zval_dtor on the readval prior
    to
    assigning the new value. Since this interface is borked it has changed
    in head. There read and write zval must be different and the caller has
    to take care about any required free/destruction. That you had a look
    into the stuff and haven't come accross this is again proof that the
    old api was not only bork but also used wrong.

    Best regards,
    Marcus

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Wez Furlong at Nov 5, 2005 at 3:38 pm

    On 11/5/05, Bob Silva wrote:
    Any word on whether the core team is going to accept the namespace patch? It
    will be beneficial to my development as well for obvious reasons.
    That's one of the things we'll be discussing in Paris next week.
    I was just reading all the Unicode docs tonight preparing to start my
    conversion to support it. Gets quite messy pretty fast.
    I'd hold off from writing any code for that just yet; we're also
    discussing some of the unicode implementation details next week.

    --Wez.
  • Jessie Hernandez at Nov 16, 2005 at 10:58 pm
    Bob,

    As mentioned, attached is what I had for the String class (have not touched
    the code for many months now). It contains the methods below. What I was
    aiming for was to have the best of the C++ and Java String methods, plus
    some new methods named after the PHP-specific string functions.

    __construct
    __toString
    append
    clear
    contains
    empty
    indexOf
    length
    makeCopy
    reserve
    startsWith
    toLowerCase
    toUpperCase
    trim


    Regards,

    Jessie Hernandez


    ""Bob Silva"" <me@bobsilva.com> wrote in message
    news:000201c5e1d5$1f85c030$5d54edc6@jake...
    Hi Jessie,

    I'd be more than happy to get some examples of how others would implement a
    string class. I am doing most of my modeling after the .NET 2.0 framework
    for my objects. I find it to be a well organized and capable framework,
    especially the new ASP.NET 2.0 features like the Role Manager. It also saves
    on my documentation, just go look at msdn2.microsoft.com. :) kidding

    I started this just for fun and an introduction to C, but I am planning on
    putting into PECL when it is stable, which is quite far off for the whole
    framework. Should be ready in time for PHP6.

    I was just reading all the Unicode docs tonight preparing to start my
    conversion to support it. Gets quite messy pretty fast.

    Any word on whether the core team is going to accept the namespace patch? It
    will be beneficial to my development as well for obvious reasons.

    Bob


    -----Original Message-----
    From: Jessie Hernandez
    Sent: Friday, November 04, 2005 9:35 PM
    To: internals@lists.php.net
    Subject: RE: [PHP-DEV] [PATCH] - Standardize argument parsing of objects

    Hi Bob,

    BTW, several months back I started working on a similar String class
    (you
    can see my post at http://news.php.net/php.pecl.dev/2512). It was meant
    as
    an OOP interface to all of the string-handling functions, and also had
    smart buffer management for speed. I started working on this hoping to
    have
    it be a part of the core, but at the time I was presented with several
    objections (most of them were because of the generic name chosen,
    "String",
    and because no one wanted it in the core, only on PECL). Even then, I
    was
    advised to wait for the Unicode changes to be merged before I continued
    (don't know if the Unicode work is done yet).

    I stopped working on this extension shortly thereafter and started
    working
    on the namespace patch (which is really more important anyways). I can
    post
    what I had done at the time if you want to take a look at it (I think I
    left the code at work, so it would have to wait till Monday).

    (IMHO, I still think a core String class would be very useful. There are
    many extensions that provide both a procedural and OOP interface. Take
    for
    example SQLite. You can either use the sqlite_* functions or use the
    SQLiteDatabase class. I don't see why strings should be any different.)


    Regards,

    Jessie


    Bob Silva wrote:
    Hi Marcus,

    I think I understand what you are saying. I've added get and set handlers
    to my objects and can now achieve this:

    $a = new ZInt(5);
    $a += 1;
    echo ($a->Equals(6)) ? 'true':'false';

    =true

    as well as:

    $a = new ZChar('A');
    $a++;
    echo ($a->Equals('B')) ? 'true':'false';

    =true

    Thanks for helping me understand this. An unexpected side-effect is
    that
    by declaring my objects ahead of time like a typed language, I can use
    natives in an object context which is what I was looking to achieve. I
    still have a lot of testing to do though.

    $a = new ZString('PHP');
    $a .= ' Object Wrappers';
    echo $a->ToString();

    =PHP Object Wrappers

    My ZString objects are immutable, $a is actually a new ZString object
    after the concatenation.

    The parameter API (even in HEAD) is still a stumbling block though
    since
    it only converts objects for "syuTt" specifiers and not the others
    ("l",
    "b", "d" and preferably "a" which doesn't look possible without
    breaking
    BC since it relies on the get_properties handler first and
    convert_object_to_type second).

    Of course any good language provides a work around: (casting ahead of
    time)

    echo wordwrap(new ZString('PHP is cool'), (int)new ZInt(3));
    =PHP
    is
    cool


    I really don't know if this will be useful for anyone else but it sure is
    fun programming it and I'm learning a lot. People that are looking for
    a
    strongly typed PHP may find it useful once I complete the rest of the
    object framework. Next up is Collections. Again, I really appreciate
    you
    taking the time to reply to my questions and point me in the right
    direction.

    Bob



    -----Original Message-----
    From: Marcus Boerger
    Sent: Friday, November 04, 2005 10:59 AM
    To: Bob Silva
    Cc: internals@lists.php.net
    Subject: Re: [PHP-DEV] [PATCH] - Standardize argument parsing of
    objects
    Hello Bob,

    Friday, November 4, 2005, 11:19:23 AM, you wrote:
    Hi Marcus,
    OK, I got my learning cap on, why is it the wrong way to call
    cast_object? I
    just copied it from the example for a string param and it worked so
    I
    am curious why it is wrong. I agree the convert_to_* functions are
    a
    better solution for the reasons you mentioned, again, I just
    followed
    the example
    for the string case.
    I guess I don't see what this modification has to do with the
    future
    of
    PHP
    though. Why restrict the parameter API to objects that can only
    convert
    to a
    string value? I'd say the current behavior is almost worthy of a
    bug.
    [...]
    In regards to the extension, I have the base objects complete:
    ZArray,
    ZChar, ZBoolean, ZDouble, ZInt, ZString. They all work
    interchangeably
    (for
    the most part) with their PHP native counterparts as long as you
    aren't
    using them on the left side of an expression.
    And that is where get/set handlers come into play and why calling cat
    handler alone is incorrect. Apart from that the 5 api has the
    parameter
    should_free which should be non null if read and write zval are the
    same
    so that the handler knows it must call zval_dtor on the readval prior
    to
    assigning the new value. Since this interface is borked it has
    changed
    in head. There read and write zval must be different and the caller
    has
    to take care about any required free/destruction. That you had a look
    into the stuff and haven't come accross this is again proof that the
    old api was not only bork but also used wrong.

    Best regards,
    Marcus

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php

    begin 666 string.c
    M(VEN8VQU9&4@(G-T<FEN9U]C;&%S<RYH(@T*#0H-"EI%3D1?1$5#3$%215]-
    M3T153$5?1TQ/0D%,4RAS=')I;F<I#0H-"GIE;F1?8VQA<W-?96YT<GD@*G-T
    M(%]S=')I;F=?;V)J96-T
    M#0I[#0H)>F5N9%]O8FIE8W0@<W1D.PT*"6-H87(@:7-?8V]P>3L-"@EE>'1?
    M<W1R('-T<CL-"GT@(V1E9FEN92!&151#2%]3
    M5%))3D=?3T)**'IV*2 H<W1R:6YG7V]B:F5C="HI>F5N9%]O8FIE8W1?<W1O
    M(%134DU,4U]#0RD-"B-D969I;F4@1$5#3$%2
    M15]35%))3D=?3T)**"D@<W1R:6YG7V]B:F5C="H@=&AI<U]O8FH@/2!&151#
    M2%]35%))3D=?3T)**&=E=%1H:7,H*2D-"B-D969I;F4@4U1224Y'7TE&7T-/
    M4%E?4D5455).*"D@7 T*"2\J(&-H96-K('1O('-E92!I9B!T:&ES(&ES(&$@
    M;F5W;'DM8W)E871E9"!C;W!Y("HO(%P-"@EI9B H=&AI<U]O8FHM/FES7V-O
    M<'DI('L@7 T*"0DO*B!I;F1I8V%T92!T:&%T('1H:7,@:7,@;F\@;&]N9V5R
    M(&$@;F5W;'DM8W)E871E9"!C;W!Y("HO(%P-"@D)=&AI<U]O8FHM/FES7V-O
    M<'D@/2 P.R!<#0H)"2\J(&EN8W)E87-E('1H92!R969E<F5N8V4@8V]U;G0@
    M;V8@=&AI<R!O8FIE8W0@<V\@=&AA="!I="!I<R!P<F5S97)V960@7 T*"0D@
    M("!W:&5N(')E='5R;F5D("HO(%P-"@D)*RMT:&ES7W!T<BT^<F5F8V]U;G0[
    M(%P-"@D)+RH@(%P-"@D)4D5455).7UI6
    M04PH=&AI<U]P='(L(# L(# I.R!<#0H)?0T*#0H-"B\J(%]?8V]N<W1R=6-T
    M(&%R9W5M96YT<R J+PT*<W1A=&EC#0I:14Y$7T)%1TE.7T%21U])3D9/*&%R
    M9VEN9F]?87)R87E?7U]C;VYS=')U8W0L(# I#0H)6D5.1%]!4D=?24Y&3R@P
    M+"!I;FET:6%L5F%L=64I#0I:14Y$7T5.1%]!4D=?24Y&3R@I.PT*#0IS=&%T
    M:6,@>F5N9%]F=6YC=&EO;E]E;G1R>2!S=')I;F=?9G5N8W1I;VYS6UT@/2![
    M#0H)4$A07TU%*%-T(&%R9VEN9F]?87)R87E?
    M7U]C;VYS=')U8W0L(# I#0H)4$A07TU%*%-T<FEN9RP@7U]T;U-T<FEN9RP@
    M3E5,3"P@,"D-"@E02%!?344H4W1R:6YG+"!A<'!E;F0L($Y53$PL(# I#0H)
    M4$A07TU%*%-T(# I#0H)4$A07TU%*%-T<FEN
    M9RP@8V]N=&%I;G,L($Y53$PL(# I#0H)4$A07TU%*%-T<FEN9RP@96UP='DL
    M($Y53$PL(# I#0H)4$A07TU%*%-T<FEN9RP@:6YD97A/9BP@3E5,3"P@,"D-
    M"@E02%!?344H4W1R:6YG+"!L96YG=&@L($Y53$PL(# I#0H)4$A07TU%*%-T
    M(# I#0H)4$A07TU%*%-T<FEN9RP@<F5S
    M97)V92P@3E5,3"P@,"D-"@E02%!?344H4W1R:6YG+"!S=&%R='-7:71H+"!.
    M54Q,+" P*0T*"5!(4%]-12A3=')I;F<L('1O3&]W97)#87-E+"!.54Q,+" P
    M*0T*"5!(4%]-12A3=')I;F<L('1O57!P97)#87-E+"!.54Q,+" P*0T*"5!(
    M4%]-12A3=')I;F<L('1R:6TL($Y53$PL(# I#0H)>TY53$PL($Y53$PL($Y5
    M3$Q]#0I].PT*#0IS=&%T:6,@>F5N9%]O8FIE8W1?:&%N9&QE<G,@<W1R:6YG
    M7V]B:F5C=%]H86YD;&5R<SL-"@T*>F5N9%]M;V1U;&5?96YT<GD@4W1R:6YG
    M7VUO9'5L95]E;G1R>2 ]('L-"B-I9F1E9B!35$%.1$%21%]-3T153$5?2$5!
    M1$52#0H@(%-404Y$05)$7TU/1%5,15](14%$15(L#0HC96YD:68-"B @(E-T
    M<FEN9R(L#0H@($Y53$PL#0H@(%!(4%]-24Y)5"A3=')I;F<I+ T*("!02%!?
    M35-(551$3U=.*%-T<FEN9RDL#0H@($Y53$PL#0H@($Y53$PL#0H@(%!(4%]-
    M24Y&3RA3=')I;F<I+ T*(VEF9&5F(%-404Y$05)$7TU/1%5,15](14%$15(-
    M"B @3D]?5D524TE/3E]9150L#0HC96YD:68-"B @4U1!3D1!4D1?34]$54Q%
    M7U!23U!%4E1)15,L#0I].PT*#0HC:69D968@0T]-4$E,15]$3%]35%))3D<-
    M"@E:14Y$7T=%5%]-3T153$4H4W1R:6YG*0T*(V5N9&EF#0H-"@T*#0HO*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ+PT*#0HO*B![>WL@<W1R
    M:6YG7VEN:71?9VQO8F%L<R J+PT*<W1A=&EC('9O:60@<W1R:6YG7VEN:71?
    M9VQO8F%L<RAZ96YD7W-T<FEN9U]G;&]B86QS("IS=')I;F=?9VQO8F%L<RD-
    M"GL-"@ES=')I;F=?9VQO8F%L<RT^<')E86QL;V-?<VEZ92 ](#$R.#L-"@ES
    M=')I;F=?9VQO8F%L<RT^<W1A<G1?<VEZ92 ](#$R.#L-"GT@+RH@?7U]("HO
    M#0H-"B\J*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHO#0H-"B\J
    M('M[>R!S=')I;F=?;V)J96-T7V9R965?<W1O<F%G92 J+PT*<W1A=&EC('9O
    M:60@<W1R:6YG7V]B:F5C=%]F<F5E7W-T;W)A9V4H=F]I9" J;V)J96-T(%13
    M4DU,4U]$0RD-"GL-"@ES=')I;F=?;V)J96-T("II;G1E<FX@/2 H<W1R:6YG
    M7V]B:F5C=" J*6]B:F5C=#L-"@T*"7IE;F1?:&%S:%]D97-T<F]Y*&EN=&5R
    M;BT^<W1D+G!R;W!E<G1I97,I.PT*"492145?2$%32%1!0DQ%*&EN=&5R;BT^
    M<W1D+G!R;W!E<G1I97,I.PT*#0H)<VUA<G1?<W1R7V9R964H)FEN=&5R;BT^
    M<W1R*3L-"@EE9G)E92AO8FIE8W0I.PT*?2 O*B!]?7T@*B\-"@T*+RHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\-"@T*<W1A=&EC('IE;F1?
    M;V)J96-T7W9A;'5E('-T<FEN9U]O8FIE8W1?;F5W7V5X*'IE;F1?8VQA<W-?
    M96YT('-T('-T<FEN
    M9U]O8FIE8W0@*F]R:6<@5%-234Q37T1#*0T*>PT*"7-T<FEN9U]O8FIE8W0@
    M*FEN=&5R;B ](&5M86QL;V,H<VEZ96]F*'-T<FEN9U]O8FIE8W0I*3L-"@EZ
    M96YD7V]B:F5C=%]V86QU92!R971V86P[#0H)>G9A;" J=&UP(#T@3E5,3#L-
    M"@T*"2\J(&EN:71I86QI>F4@=&AE('-T<FEN9R!O8FIE8W0@*B\-"@EM96US
    M970H:6YT97)N+" P+"!S:7IE;V8H<W1R:6YG7V]B:F5C="DI.PT*"6EN=&5R
    M;BT^<W1D+F-E(#T@8VQA(#T@:6YT97)N.PT*#0H)
    M+RH@:6YI=&EA;&EZ92!T:&4@<')O<&5R=&EE<R!H87-H=&%B;&4@*B\-"@E!
    M3$Q/0U](05-(5$%"3$4H:6YT97)N+3YS=&0N<')O<&5R=&EE<RD[#0H)>F5N
    M9%]H87-H7VEN:70H:6YT97)N+3YS=&0N<')O<&5R=&EE<RP@,"P@3E5,3"P@
    M6E9!3%]05%)?1%1/4BP@,"D[#0H)>F5N9%]H87-H7V-O<'DH:6YT97)N+3YS
    M=&0N<')O<&5R=&EE<RP@)F-L87-S7W1Y<&4M/F1E9F%U;'1?<')O<&5R=&EE
    M('IV86Q?861D7W)E9BP@*'9O:60@*BD@
    M)G1M<"P@<VEZ96]F*'IV86P@*BDI.PT*#0H)+RH@8VAE8VL@=&\@<V5E(&EF
    M('=E(&%C='5A;&QY(&YE960@=&\@;6%K92!A(&-O<'D@*B\-"@EI9B H;W)I
    M9R A/2!.54Q,*2![#0H)"2\J(&EN9&EC871E('1H870@=&AI<R!I<R!N;W0@
    M82!N97=L>2UC<F5A=&5D(&-O<'D@*B\-"@D):6YT97)N+3YI<U]C;W!Y(#T@
    M,#L-"@T*"0DO*B!C;W!Y('1H92!L96YG=&@@86YD('-I>F4@<')O<&5R=&EE
    M<R J+PT*"0EI;G1E(N;&5N.PT*"0EI
    M;G1E[#0H-"@D)+RH@;6%K92!A(&-O
    M<'D@;V8@=&AE('-T<FEN9R!V86QU92 J+PT*"0EI;G1E<FXM/G-T<BYC(#T@
    M96UA;&QO8RAO<FEG+3YS='(N;&5N*3L-"@D);65M8W!Y*&EN=&5R;BT^<W1R
    M+F,L(&]R:6[#0H)?2 O*B!E
    M;F1I9B J+PT*#0H)+RH@<V5T('1H92!O8FIE8W0@:&%N9&QE<G,@*B\-"@ER
    M971V86PN:&%N9&QE(#T@>F5N9%]O8FIE8W1S7W-T;W)E7W!U="AI;G1E<FXL
    M($Y53$PL("AZ96YD7V]B:F5C='-?9G)E95]O8FIE8W1?<W1O<F%G95]T*2!S
    M=')I;F=?;V)J96-T7V9R965?<W1O<F%G92P@3E5,3"!44U)-3%-?0T,I.PT*
    M"7)E='9A;"YH86YD;&5R<R ]("9S=')I;F=?;V)J96-T7VAA;F1L97)S.PT*
    M#0H)<F5T=7)N(')E='9A;#L-"GT-"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*B\-"@T*<W1A=&EC('IE;F1?;V)J96-T7W9A;'5E('-T
    M<FEN9U]O8FIE8W1?;F5W*'IE;F1?8VQA<W-?96YT<GD@*F-L87-S7W1Y<&4@
    M5%-234Q37T1#*0T*>PT*"7-T<FEN9U]O8FIE8W0@*G1M<" ]($Y53$P[#0H)
    M<F5T=7)N('-T<FEN9U]O8FIE8W1?;F5W7V5X*&-L87-S7W1Y<&4L("9T;7 L
    M($Y53$P@5%-234Q37T-#*3L-"GT-"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*B\-"@T*<W1A=&EC(&5X=%]S='(@<W1R:6YG7WIV86Q?
    M=&]?97AT7W-T(%134DU,4U]$0RD-"GL-"@EE>'1?<W1R
    M(')E("A:7U194$5?4% H<W1R*2 ]/2!)4U]/0DI%0U0@
    M)B8@6E]/0DI#15]04"AS='(I(#T]('-T<FEN9U]C95]P='(I('L-"@D)<W1R
    M:6YG7V]B:F5C="H@<W1R:6YG7V]B:B ]($9%5$-(7U-44DE.1U]/0DHH*G-T
    M<BD[#0H-"@D)(N8SL-"@D)<F5S
    M=6QT+FQE;B ]('-T<FEN9U]O8FHM/G-T<BYL96X[#0H)?0T*"65L<V4@>PT*
    M"0DO*B!C87-T('1H:7,@=F%L=64@=&\@82!S=')I;F<@*B\-"@D)8V]N=F5R
    M=%]T;U]S=')I;F=?97@H<W1R*3L-"@T*"0ER97-U;'0N8R ](%I?4U125D%,
    M7U!0*'-T(I.PT*
    M"7T-"@T*"7)E='5R;B!R97-U;'0[#0I]#0H-"B\J*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHO#0H-"B\J('M[>R!S=')I;F=?;V)J96-T7V-A
    M<W0@*B\-"G-T871I8R!I;G0@<W1R:6YG7V]B:F5C=%]C87-T*'IV86P@*G)E
    M861O8FHL('IV86P@*G=R:71E;V)J+"!I;G0@='EP92P@:6YT('-H;W5L9%]F
    M(&9R965?;V)J.PT*"6EN="!R97-U
    M;'0@/2!354-#15-3.PT*"7-T<FEN9U]O8FIE8W0J('-T<FEN9U]O8FH@/2!&
    M151#2%]35%))3D=?3T)**')E861O8FHI.PT*#0H):68@*'-H;W5L9%]F<F5E
    M*2![#0H)"69R965?;V)J(#T@*G=R:71E;V)J.PT*"7T-"@T*"2\J(&-O<'D@
    M=&AE('-T('IV86P@*B\-"@E:5D%,
    M7U-44DE.1TPH=W)I=&5O8FHL('-T<FEN9U]O8FHM/G-T<BYC+"!S=')I;F=?
    M;V)J+3YS='(N;&5N+" Q*3L-"@EW<FET96]B:BT^<F5F8V]U;G0@/2 Q.PT*
    M"7=R:71E;V)J+3YI<U]R968@/2 P.PT*#0H)+RH@8V]N=F5R="!T:&4@>G9A
    M;"!T;R!T:&4@87!P<F]P<FEA=&4@='EP92 J+PT*"7-W:71C:" H='EP92D@
    M>PT*"0EC87-E($E37U-44DE.1SH-"@D)"6-O;G9E<G1?=&]?<W1R:6YG*'=R
    M:71E;V)J*3L-"@D)"6)R96%K.PT*"0EC87-E($E37T)/3TPZ#0H)"0EC;VYV
    M97)T7W1O7V)O;VQE86XH=W)I=&5O8FHI.PT*"0D)8G)E86L[#0H)"6-A<V4@
    M25-?3$].1SH-"@D)"6-O;G9E<G1?=&]?;&]N9RAW<FET96]B:BD[#0H)"0EB
    M<F5A:SL-"@D)8V%S92!)4U]$3U5"3$4Z#0H)"0EC;VYV97)T7W1O7V1O=6)L
    M92AW<FET96]B:BD[#0H)"0EB<F5A:SL-"@D)9&5F875L=#H-"@D)"7)E<W5L
    M=" ]($9!24Q54D4[#0H)?0T*#0H):68@*'-H;W5L9%]F<F5E*2![#0H)"7IV
    M86Q?9'1O<B@F9G)E95]O8FHI.PT*"7T-"@T*"7)E='5R;B!R97-U;'0[#0I]
    M#0HO*B!]?7T@*B\-"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*B\-"@T*+RH@>WM[('-T<FEN9U]O8FIE8W1?8VQO;F5?97@@*B\-"G-T
    M871I8R!Z96YD7V]B:F5C=%]V86QU92!S=')I;F=?;V)J96-T7V-L;VYE7V5X
    M*'IV86P@*GIO8FIE8W0L('-T<FEN9U]O8FIE8W0@*BIO8FH@5%-234Q37T1#
    M*0T*>PT*"7IE;F1?;V)J96-T7VAA;F1L92!H86YD;&4@/2!:7T]"2E](04Y$
    M3$5?4"AZ;V)J96-T*3L-"@ES=')I;F=?;V)J96-T("II;G1E<FX@/2!.54Q,
    M.PT*"7IE;F1?;V)J96-T("IO;&1?;V)J96-T.PT*"7IE;F1?;V)J96-T7W9A
    M;'5E(&YE=U]O8FI?=F%L.PT*"7IE;F1?;V)J96-T("IN97=?;V)J96-T.PT*
    M#0H);VQD7V]B:F5C=" ]('IE;F1?;V)J96-T<U]G971?861D<F5S<RAZ;V)J
    M96-T(%134DU,4U]#0RD[#0H);F5W7V]B:E]V86P@/2!S=')I;F=?;V)J96-T
    M7VYE=U]E>"AO;&1?;V)J96-T+3YC92P@)FEN=&5R;BP@*'-T<FEN9U]O8FIE
    M8W0J*6]L9%]O8FIE8W0@5%-234Q37T-#*3L-"@EN97=?;V)J96-T(#T@)FEN
    M=&5R;BT^<W1D.PT*#0H):68@*&]B:B A/2!.54Q,*0T*"0DJ;V)J(#T@:6YT
    M97)N.PT*#0H)>F5N9%]O8FIE8W1S7V-L;VYE7VUE;6)E<G,H;F5W7V]B:F5C
    M="P@;F5W7V]B:E]V86PL(&]L9%]O8FIE8W0L(&AA;F1L92!44U)-3%-?0T,I
    M.PT*#0H)("HO#0H-"B\J
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHO#0H-"B\J('M[>R!S
    M=')I;F=?;V)J96-T7V-L;VYE("HO#0IS=&%T:6,@>F5N9%]O8FIE8W1?=F%L
    M=64@<W1R:6YG7V]B:F5C=%]C;&]N92AZ=F%L("IZ;V)J96-T(%134DU,4U]$
    M0RD-"GL-"@ER971U<FX@<W1R:6YG7V]B:F5C=%]C;&]N95]E>"AZ;V)J96-T
    M+"!.54Q,(%134DU,4U]#0RD[#0I]#0HO*B!]?7T@*B\-"@T*+RHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\-"@T*+RH@>WM[('-T<FEN9U]O
    M8FIE8W1?<F5A9%]D:6UE;G-I;VX@*B\-"G-T871I8R!Z=F%L*B!S=')I;F=?
    M;V)J96-T7W)E861?9&EM96YS:6]N*'IV86P@*F]B:F5C="P@>G9A;" J;V9F
    M(#T@
    M,#L-"@EZ=F%L*B!R97-U;'0@/2!%1RAU;FEN:71I86QI>F5D7WIV86Q?<'1R
    M*3L-"@ES=')I;F=?;V)J96-T*B!S=')I;F=?;V)J(#T@1D540TA?4U1224Y'
    M7T]"2BAO8FIE8W0I.PT*#0H)<W=I=&-H*%I?5%E015]0*&]F9G-E="DI('L-
    M"@D)8V%S92!)4U]$3U5"3$4Z#0H)"6-A<V4@25-?4D533U520T4Z#0H)"6-A
    M<V4@25-?0D]/3#H@#0H)"6-A<V4@25-?3$].1SH@#0H)"0EI9B H;V9F<V5T
    M+3YT>7!E(#T]($E37T1/54),12D@>PT*"0D)"6EN9&5X(#T@*'-I>F5?="E:
    M7T1604Q?4"AO9F9S970I.R!]#0H)"0EE;'-E('L-"@D)"0EI;F1E>" ](%I?
    M3%9!3%]0*&]F9G-E="D[('T-"@T*"0D):68@*&EN9&5X(#P@,"!\?"!I;F1E
    M>" ^/2!S=')I;F=?;V)J+3YS='(N;&5N*2![#0H)"0D)>F5N9%]E<G)O<BA%
    M7TY/5$E#12P@(E5N9&5F:6YE9"!O9F9S970Z(" E;&0B+"!:7TQ604Q?4"AO
    M9F9S970I*3L-"@D)"7T@96QS92![#0H)"0D)04Q,3T-?6E9!3"AR97-U;'0I
    M.PT*"0D)"5I604Q?4U1224Y'3"AR97-U;'0L("9S=')I;F=?;V)J+3YS='(N
    M8UMI;F1E>%TL(#$L(#$I.PT*"0D)?0T*#0H)"0EB<F5A:SL-"@D)9&5F875L
    M=#H-"@D)"7IE;F1?97)R;W(H15]705).24Y'+" B26QL96=A;"!O9F9S970@
    M='EP92(I.PT*"7T-"@T*"7)E='5R;B!R97-U;'0[#0I]#0HO*B!]?7T@*B\-
    M"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\-"@T*4$A0
    M7TU)3D9/7T953D-424].*%-T<FEN9RD-"GL-"@EP:'!?:6YF;U]P<FEN=%]T
    M86)L95]S=&%R="@I.PT*"7!H<%]I;F9O7W!R:6YT7W1A8FQE7W)O=R@R+" B
    M4W1R:6YG($-L87-S(BP@(F5N86)L960B*3L-"@EP:'!?:6YF;U]P<FEN=%]T
    M86)L95]E;F0H*3L-"@DO*D1)4U!,05E?24Y)7T5.5%))15,H*3LJ+PT*?0T*
    M#0HO*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ+PT*#0I02%!?
    M34E.251?1E5.0U1)3TXH4W1R:6YG*0T*>PT*"7IE;F1?8VQA<W-?96YT<GD@
    M<W1R:6YG7V-E.PT*"4E.251?0TQ!4U-?14Y44EDH<W1R:6YG7V-E+" B4W1R
    M:6YG(BP@<W1R:6YG7V9U;F-T:6]N<RD[#0H)<W1R:6YG7V-E+F-R96%T95]O
    M8FIE8W0@/2!S=')I;F=?;V)J96-T7VYE=SL-"@ES=')I;F=?8V5?<'1R(#T@
    M>F5N9%]R96=I(%134DU,
    M4U]#0RD[#0H-"@DO*B!I;FET:6%L:7IE('1H92!G;&]B86P@=F%R:6%B;&5S
    M("HO#0H)6D5.1%])3DE47TU/1%5,15]'3$]"04Q3*'-T<FEN9RP@<W1R:6YG
    M7VEN:71?9VQO8F%L[#0H-"@DO*B!I;FET:6%L:7IE('1H92!O
    M8FIE8W0@:&%N9&QE<G,@*B\-"@EM96UC<'DH)G-T<FEN9U]O8FIE8W1?:&%N
    M9&QE<G,L('IE;F1?9V5T7W-T9%]O8FIE8W1?:&%N9&QE<G,H*2P@<VEZ96]F
    M*'IE;F1?;V)J96-T7VAA;F1L97)S*2D[#0H)<W1R:6YG7V]B:F5C=%]H86YD
    M;&5R<RYC87-T7V]B:F5C=" ]('-T<FEN9U]O8FIE8W1?8V%S=#L-"@ES=')I
    M;F=?;V)J96-T7VAA;F1L97)S+F-L;VYE7V]B:B ]('-T<FEN9U]O8FIE8W1?
    M8VQO;F4[#0H)<W1R:6YG7V]B:F5C=%]H86YD;&5R<RYR96%D7V1I;65N<VEO
    M;B ]('-T<FEN9U]O8FIE8W1?<F5A9%]D:6UE;G-I;VX[#0H-"@ER971U<FX@
    M4U5#0T534SL-"GT-"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*B\-"@T*4$A07TU32%541$]73E]&54Y#5$E/3BA3=')I;F<I#0I[#0H)
    M<F5T=7)N(%-50T-%4U,[#0I]#0H-"B\J*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHO#0H-"B\J('M[>R!P<F]T;R!3=')I;F<Z.E]?8V]N<W1R
    M=6-T*%MS=')I;F<@:6YI=&EA;%9A;'5E(#T@)R==*0T*(" @0V]N<W1R=6-T
    M('1H92!S<&5C
    M:69I960@<W1R:6YG('9A;'5E+B J+PT*4$A07TU%5$A/1"A3=')I;F<L(%]?
    M8V]N<W1R=6-T*0T*>PT*"6-H87(J(&EN:71I86Q?=F%L=64@/2!.54Q,.PT*
    M"6QO;F<@:6YI=&EA;%]V86QU95]L96X@/2 P.PT*"41%0TQ!4D5?4U1224Y'
    M7T]"2B@I.PT*#0H):68@*'IE;F1?<&%R<V5?<&%R86UE=&5R<RA:14Y$7TY5
    M35]!4D=3*"D@5%-234Q37T-#+" B?',B+" F:6YI=&EA;%]V86QU92P@)FEN
    M:71I86Q?=F%L=65?;&5N*2 ]/2!&04E,55)%*2![#0H)"7)E='5R;CL-"@E]
    M#0H-"@EI9B H:6YI=&EA;%]V86QU92 A/2!.54Q,*2![#0H)"2\J(&UA:V4@
    M82!C;W!Y(&]F('1H92!I;FET:6%L('9A;'5E("HO#0H)"71H:7-?;V)J+3YS
    M='(N8R ](&5S=')D=7 H:6YI=&EA;%]V86QU92D[#0H)"71H:7-?;V)J+3YS
    M='(N;&5N(#T@:6YI=&EA;%]V86QU95]L96X[#0H)"71H:7-?;V)J+3YS='(N
    M82 ](&EN:71I86Q?=F%L=65?;&5N.PT*"7T-"@EE;'-E("\J(&EN:71I86Q6
    M86QU92 ]/2!.54Q,("HO('L-"@D)+RH@:6YD:6-A=&4@=&AA="!T:&ES(&ES
    M(&%N(&5M<'1Y('-T<FEN9R J+PT*"0ET:&ES7V]B:BT^<W1R+FQE;B ](# [
    M#0H)"71H:7-?;V)J+3YS='(N82 ](# [#0H-"@D)+RH@8W)E871E(&%N(&5M
    M<'1Y('-T<FEN9R J+PT*"0ET:&ES7V]B:BT^<W1R+F,@/2!E;6%L;&]C*#$I
    M.PT*"0DJ=&AI<U]O8FHM/G-T<BYC(#T@)UPP)SL-"@E]#0I]#0HO*B!]?7T@
    M*B\-"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\-"@T*
    M+RH@>WM[('!R;W1O(%-T<FEN9SHZ7U]T;U-T<FEN9R@I#0H@("!2971U<FYS
    M('1H92!S=')I;F<@=F%L=64@;V8@=&AI<R!3=')I;F<@;V)J96-T+B J+PT*
    M4$A07TU%5$A/1"A3=')I;F<L(%]?=&]3=')I;F<I#0I[#0H)1$5#3$%215]3
    M5%))3D=?3T)**"D[#0H)4D5455).7U-44DE.1TPH=&AI<U]O8FHM/G-T<BYC
    M+"!T:&ES7V]B:BT^[#0I]#0HO*B!]?7T@*B\-"@T*+RHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\-"@T*4$A07TU%5$A/
    M1"A3=')I;F(#T@3E5,3#L-"@EE
    M>'1?<W1R('9A;'5E.PT*"41%0TQ!4D5?4U1224Y'7T]"2B@I.PT*#0H):68@
    M*%I%3D1?3E5-7T%21U,H*2 A/2 Q('Q\('IE;F1?9V5T7W!A<F%M971E<G-?
    M97@H,2P@)G-T[#0H)?0T*#0H)
    M=F%L=64@/2!S=')I;F=?>G9A;%]T;U]E>'1?<W1R*'-T<B!44U)-3%-?0T,I
    M.PT*#0H)+RH@87!P96YD('1H92!P87-S960@=F%L=64@*B\-"@EE>'1?<W1R
    M7V%P<&5N9&PH)G1H:7-?;V)J+3YS='(L('9A;'5E+F,L('9A;'5E+FQE;BP@
    M4U1224Y'7T<H<W1A<G1?<VEZ92DL(%-44DE.1U]'*'!R96%L;&]C7W-I>F4I
    M*3L-"GT-"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\-
    M"@T*+RH@>WM[('!R;W1O(%-T<FEN9SHZ8VQE87(H*0T*(" @0VQE87)S('1H
    M92!S=')I;F<@8V]N=&5N=',L(&UA:VEN9R!T:&4@;F5W('9A;'5E(&%N(&5M
    M(3T0H4W1R:6YG+"!C;&5A<BD-"GL-
    M"@E$14-,05)%7U-44DE.1U]/0DHH*3L-"@ET:&ES7V]B:BT^<W1R+FQE;B ]
    M(# [#0H)*G1H:7-?;V)J+3YS='(N8R ]("=<,"<[#0I]#0HO*B!]?7T@*B\-
    M"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\-"@T*+RH@
    M>WM[('!R;W1O(&)O;VP@4W1R:6YG.CIC;VYT86EN<RAS=')I;F<@=F%L=64I
    M#0H@("!2971U<FYS('1R=64@:68@86YD(&]N;'D@:68@=&AI<R!S=')I;F<@
    M8V]N=&%I;G,@=&AE('-U8G-T<FEN9R!S<&5C:69I960@8GD@/&D^=F%L=64\
    M+VD^+B J+PT*4$A07TU%5$A/1"A3=')I;F<L(&-O;G1A:6YS*0T*>PT*"6-H
    M87(J('9A;'5E(#T@,#L-"@EL;VYG('9A;'5E7VQE;B ](# [#0H)1$5#3$%2
    M15]35%))3D=?3T)**"D[#0H-"@EI9B H>F5N9%]P87)S95]P87)A;65T97)S
    M*%I%3D1?3E5-7T%21U,H*2!44U)-3%-?0T,L(")S(BP@)G9A;'5E+" F=F%L
    M=65?;&5N*2 ]/2!&04E,55)%*2![#0H)"7)E='5R;CL-"@E]#0H-"@EI9B@@
    M<&AP7VUE;6YS='(H=&AI<U]O8FHM/G-T<BYC+"!V86QU92P@=F%L=65?;&5N
    M+"!T:&ES7V]B:BT^<W1R+F,@*R!T:&ES7V]B:BT^[#0H)
    M"5)%5%523E]44E5%.PT*"7T-"@EE;'-E("\J(&YO="!F;W5N9" J+R![#0H)
    M"5)%5%523E]&04Q313L-"@E]#0I]#0HO*B!]?7T@*B\-"@T*+RHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\-"@T*4$A07TU%5$A/1"A3=')I
    M;F<L(&5M<'1Y*0T*>PT*"41%0TQ!4D5?4U1224Y'7T]"2B@I.PT*"5)%5%52
    M3E]"3T],*"%T:&ES7V]B:BT^<W1R+FQE;BD[#0I]#0H-"B\J*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHO#0H-"E!(4%]-151(3T0H4W1R:6YG
    M+"!I;F1E>$]F*0T*>PT*"6QO;F<@9G)O;5]I;F1E>" ](# [#0H)8VAA<BH@
    M:6YD97A3='(@/2!.54Q,.PT*"6-H87(J('-T<B ]($Y53$P[#0H);&]N9R!S
    M='),96X@/2 P.PT*"41%0TQ!4D5?4U1224Y'7T]"2B@I.PT*#0H):68@*'IE
    M;F1?<&%R<V5?<&%R86UE=&5R<RA:14Y$7TY535]!4D=3*"D@5%-234Q37T-#
    M+" B<WQL(BP@)G-T<BP@)G-T<DQE;BP@)F9R;VU?:6YD97@I(#T]($9!24Q5
    M4D4I('L-"@D)(&9I;F0@=&AE(&9I<G-T(&]C
    M8W5R<F5N8V4@;V8@=&AE('-P96-I9FEE9"!S=6)S=')I;F<@*B\-"@EI;F1E
    M>%-T<B ]('!H<%]M96UN<W1R*'1H:7-?;V)J+3YS='(N8R K(&9R;VU?:6YD
    M97@L('-T<BP@<W1R3&5N+"!T:&ES7V]B:BT^<W1R+F,@*R!F<F]M7VEN9&5X
    M("L@*'1H:7-?;V)J+3YS='(N;&5N("T@9G)O;5]I;F1E>"DI.PT*#0H):68@
    M*&EN9&5X4W1R("$]($Y53$PI('L-"@D)4D5455).7TQ/3D<H:6YD97A3='(@
    M+2!T:&ES7V]B:BT^(&EN9&5X3V8@/3T@
    M3E5,3" J+R![#0H)"5)%5%523E]&04Q313L-"@E]#0I]#0H-"B\J*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHO#0H-"E!(4%]-151(3T0H4W1R
    M:6YG+"!L96YG=&@I#0I[#0H)1$5#3$%215]35%))3D=?3T)**"D[#0H)4D54
    M55).7TQ/3D<H=&AI<U]O8FHM/G-T<BYL96XI.PT*?0T*#0HO*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ+PT*#0I02%!?34542$]$*%-T<FEN
    M9RP@;6%K94-O<'DI#0I[#0H)<W1R:6YG7V]B:F5C="H@8V]P>5]O8FH@/2!.
    M54Q,.PT*#0H)<F5T=7)N7W9A;'5E+3YT>7!E(#T@25-?3T)*14-4.PT*"7)E
    M='5R;E]V86QU92T^=F%L=64N;V)J(#T@<W1R:6YG7V]B:F5C=%]C;&]N95]E
    M>"AG9714:&ES*"DL("9C;W!Y7V]B:B!44U)-3%-?0T,I.PT*#0H)+RH@:6YD
    M:6-A=&4@=&AA="!T:&ES(&ES(&$@;F5W;'DM8W)E871E9"!C;W!Y("HO#0H)
    M8V]P>5]O8FHM/FES7V-O<'D@/2 Q.PT*?0T*#0HO*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ+PT*#0I02%!?34542$]$*%-T<FEN9RP@<F5S
    M97)V92D-"GL-"@ES:7IE7W0@<F5S97)V95-I>F4@/2 P.PT*"41%0TQ!4D5?
    M4U1224Y'7T]"2B@I.PT*#0H):68@*'IE;F1?<&%R<V5?<&%R86UE=&5R<RA:
    M14Y$7TY535]!4D=3*"D@5%-234Q37T-#+" B;"(L("9R97-E<G9E4VEZ92D@
    M/3T@1D%)3%5212D@>PT*"0ER971U<FX[#0H)?0T*#0H):68@*'1H:7-?;V)J
    M+3YS='(N82 \(')E<V5R=F53:7IE*2![#0H)"71H:7-?;V)J+3YS='(N82 ]
    M(')E<V5R=F53:7IE.PT*"0E%6%1?4U127T1/7U)%04Q,3T,H)G1H:7-?;V)J
    M+3YS='(L(# I.PT*"7T-"GT-"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*B\-"@T*4$A07TU%5$A/1"A3=')I;F<L('-T87)T<U=I=&@I
    M#0I[#0H)8VAA(#T@3E5,3#L-"@EL;VYG(&]F9G-E=" ]
    M(# [#0H)8VAA(#T@3E5,3#L-"@EL;VYG('!R969I>%]L96X@
    M/2 P.PT*"41%0TQ!4D5?4U1224Y'7T]"2B@I.PT*#0H):68@*'IE;F1?<&%R
    M<V5?<&%R86UE=&5R<RA:14Y$7TY535]!4D=3*"D@5%-234Q37T-#+" B<WQL
    M(BP@)G!R969I>"P@)G!R969I>%]L96XL("9O9F9S970I(#T]($9!24Q54D4I
    M('L-"@D)(&9I;F0@=&AE(&9I<G-T(&]C8W5R
    M<F5N8V4@;V8@=&AE('-P96-I9FEE9"!S=6)S=')I;F<@*B\-"@EI;F1E>%]S
    M='(@/2!P:'!?;65M;G-T('!R
    M969I>"P@("L@;V9F<V5T("L@
    M*'1H:7-?;V)J+3YS='(N;&5N("T@;V9F<V5T*2D[#0H-"@EI9B H:6YD97A?
    M<W1R("$]($Y53$P@)B8@:6YD97A?<W1R(#T]('1H:7-?;V)J+3YS='(N8RD@
    M>PT*"0E215154DY?5%)513L-"@E]#0H)96QS92 O*B!I;F1E>$]F(#T]($Y5
    M3$P@?'P@:6YD97A3='(@(3T@=&AI<U]O8FHM/G9A;'5E("HO('L-"@D)4D54
    M55).7T9!3%-%.PT*"7T-"GT-"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*B\-"@T*4$A07TU%5$A/1"A3=')I;F<L('1O3&]W97)#87-E
    M*0T*>PT*"2\J(&QO=V5R8V%S92!T:&4@<W1R:6YG("HO#0H)1$5#3$%215]3
    M5%))3D=?3T)**"D[#0H)<&AP7W-T<G1O;&]W97(H=&AI<U]O8FHM/G-T<BYC
    M+"!T:&ES7V]B:BT^<W1R+FQE;BD[#0H-"@E35%))3D=?249?0T]065]21515
    M4DXH*3L-"GT-"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*B\-"@T*4$A07TU%5$A/1"A3=')I;F<L('1O57!P97)#87-E*0T*>PT*"2\J
    M('5P("HO#0H)1$5#3$%215]35%))3D=?3T)*
    M*"D[#0H)<&AP7W-T<G1O=7!P97(H=&AI<U]O8FHM/G-T<BYC+"!T:&ES7V]B
    M:BT^<W1R+FQE;BD[#0H-"@E35%))3D=?249?0T]065]215154DXH*3L-"GT-
    M"@T*+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ
    M*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*B\-"@T*4$A0
    M7TU%5$A/1"A3=')I;F<L('1R:6TI#0I[#0H)8VAA<BH@8VAA<DQI<W0@/2!.
    M54Q,.PT*"6QO;F<@8VAA<DQI<W1,96X@/2 P.PT*"41%0TQ!4D5?4U1224Y'
    M7T]"2B@I.PT*#0H):68@*'IE;F1?<&%R<V5?<&%R86UE=&5R<RA:14Y$7TY5
    M35]!4D=3*"D@5%-234Q37T-#+" B?',B+" F8VAA<DQI<W0L("9C:&%R3&ES
    M=$QE;BD@/3T@1D%)3%5212D@>PT*"0ER971U<FX[#0H)?0T*#0H)<&AP7W1R
    M:6TH=&AI<U]O8FHM/G-T<BYC+"!T:&ES7V]B:BT^<W1R+FQE;BP@8VAA<DQI
    M<W0L(&-H87),:7-T3&5N+"!R971U<FY?=F%L=64L(#,@5%-234Q37T-#*3L-
    A"@T*"5-44DE.1U])1E]#3U!97U)%5%523B@I.PT*?0T*
    `
    end

    begin 666 string_class.h
    M(VEF;F1E9B!02%!?4U1224Y'7T-,05-37T@-"B-D969I;F4@4$A07U-44DE.
    M1U]#3$%34U](#0H-"B-I;F-L=61E(#QZ96YD+F@^#0HC:6YC;'5D92 B<&AP
    M+F@B#0HC:6YC;'5D92 B<&AP7V=L;V)A;',N:"(-"B-I;F-L=61E(")P:'!?
    M:6YI+F@B#0HC:6YC;'5D92 B97AT+W-T86YD87)D+VEN9F\N:"(-"B-I;F-L
    M=61E(")E>'0O(VEN8VQU9&4@
    M(F5X="]S=&%N9&%R9"]P:'!?(059%7T-/
    M3D9)1U](#0HC:6YC;'5D92 B8V]N9FEG+F@B#0HC96YD:68-"@T*(VEF9&5F
    M(%I44PT*(VEN8VQU9&4@(E134DTN:"(-"B-E;F1I9@T*#0IT>7!E9&5F('-T
    M(&QE;CL-
    M"@ES:7IE7W0@83L-"GT@97AT7W-T<CL-"@T*='EP961E9B!S=')U8W0@7V5X
    M=%]W<W1R:6YG#0I[#0H)=6YS:6=N960@(&QE
    M;CL-"@ES:7IE7W0@83L-"GT@97AT7W=S='([#0H-"@T*(VEF9&5F($585%]3
    M5%)?55-%7U)%04Q,3T,-"B-D969I;F4@15A47U-44E]214%,3$]#*&$L8BQC
    M*2!R96%L;&]C*"AA*2PH8BDI#0HC96QS90T*(V1E9FEN92!%6%1?4U127U)%
    M04Q,3T,H82QB+&,I('!E(I+"AC*2D-"B-E;F1I9@T*
    M#0HC9&5F:6YE($585%]35%)?1$]?4D5!3$Q/0RAD97-T+"!W:&%T*2!<#0H)
    M*&1E<W0I+3YC(#T@15A47U-44E]214%,3$]#*"AD97-T*2T^8RP@*&1E<W0I
    M+3YA("L@,2P@*'=H870I*0T*#0HC9&5F:6YE(&5X=%]S=')?86QL;V,H9&5S
    M="P@<VEZ92P@=VAA="P@;F5W;&5N+"!S=&%R=%]S:7IE+"!P<F5A;&QO8U]S
    M:7IE*0D)"5P-"GL)"0D)"0D)"0D)"0D)"0D)"0D)"0E<#0H):68@*"$H9&5S
    M="DM/F,I('L)"0D)"0D)"0D)"0D)"0D)7 T*"0DH9&5S="DM/FQE;B ](# [
    M"0D)"0D)"0D)"0D)"0D)7 T*"0EN97=L96X@/2 H<VEZ92D["0D)"0D)"0D)
    M"0D)"0D)7 T*"0DH9&5S="DM/F$@/2 H(&YE=VQE;B \('-T87)T7W-I>F4@
    M/R!S=&%R=%]S:7IE(#H@;F5W;&5N("L@<')E86QL;V-?<VEZ92 I.PE<#0H)
    M"4585%]35%)?1$]?4D5!3$Q/0RAD97-T+"!W:&%T*3L)"0D)"0D)"0D)"0E<
    M#0H)?2!E;'-E('L)"0D)"0D)"0D)"0D)"0D)"0E<#0H)"6YE=VQE;B ]("AD
    M97-T*2T^;&5N("L@*'-I>F4I.PD)"0D)"0D)"0D)"5P-"@D):68@*&YE=VQE
    M;B ^/2 H9&5S="DM/F$I('L)"0D)"0D)"0D)"0D)7 T*"0D)*&1E<W0I+3YA
    M(#T@;F5W;&5N("L@<')E86QL;V-?<VEZ93L)"0D)"0D)"0D)7 T*"0D)15A4
    M7U-44E]$3U]214%,3$]#*&1E<W0L('=H870I.PD)"0D)"0D)"0D)7 T*"0E]
    M"0D)"0D)"0D)"0D)"0D)"0D)"5P-"@E]"0D)"0D)"0D)"0D)"0D)"0D)"0E('-R8RP@;FQE
    M;BP@<W1A<G1?<VEZ92P@<')E86QL;V-?<VEZ92D)7 T*>PD)"0D)"0D)"0D)
    M"0E["0D)"0D)"5P-"@EE>'1?<W1R
    M7V%L;&]C*&1E<W0L("AN;&5N*2P@,"P@7U]N;"P@<W1A<G1?<VEZ92P@<')E
    M86QL;V-?("L@*&1E<W0I+3YL
    M96XL("AS<F,I+" H;FQE;BDI.R!<#0H)*&1E<W0I+3YL96X@/2!?7VYL.PD)
    M"0D)"0D)7 T*?0T*#0H-"@T*97AT97)N('IE;F1?;6]D=6QE7V5N=')Y('-T
    M<FEN9U]M;V1U;&5?96YT<GD[#0H-"@T*#0I:14Y$7T)%1TE.7TU/1%5,15]'
    M3$]"04Q3*'-T<FEN9RD-"@ES:7IE7W0@<')E86QL;V-?<VEZ93L-"@ES:7IE
    M7W0@<W1A<G1?<VEZ93L-"EI%3D1?14Y$7TU/1%5,15]'3$]"04Q3*'-T<FEN
    M9RD-"@T*(VEF9&5F(%I44PT*(V1E9FEN92!35%))3D=?1RAV*2!44U)-1RAS
    M=')I;F=?9VQO8F%L<U]I9"P@>F5N9%]S=')I;F=?9VQO8F%L<R J+"!V*0T*
    M(V5L<V4-"B-D969I;F4@4U1224Y'7T<H=BD@*'-T<FEN9U]G;&]B86QS+G8I
    M#0HC96YD:68-"@T*4$A07TU)3D9/7T953D-424].*%-T<FEN9RD[#0I02%!?
    M34E.251?1E5.0U1)3TXH4W1R:6YG*3L-"E!(4%]-4TA55$1/5TY?1E5.0U1)
    M3TXH4W1R:6YG*3L-"@T*+RH@4W1R:6YG(&-L87-S(&UE=&AO9',@*B\-"E!(
    M4%]-151(3T0H4W1R:6YG+"!?7V-O;G-T<G5C="D[#0I02%!?34542$]$*%-T
    M[#0I02%!?34542$]$*%-T<FEN9RP@87!P96YD
    M*3L-"E!(4%]-151(3T0H4W1R:6YG+"!C;&5A<BD[#0I02%!?34542$]$*%-T
    M(&5M<'1Y*3L-
    M"E!(4%]-151(3T0H4W1R:6YG+"!I;F1E>$]F*3L-"E!(4%]-151(3T0H4W1R
    M:6YG+"!L96YG=&@I.PT*4$A07TU%5$A/1"A3=')I;F<L(&UA:V5#;W!Y*3L-
    M"E!(4%]-151(3T0H4W1R:6YG+"!R97-E<G9E*3L-"E!(4%]-151(3T0H4W1R
    M:6YG+"!S=&%R='-7:71H*3L-"E!(4%]-151(3T0H4W1R:6YG+"!T;TQO=V5R
    M0V%S92D[#0I02%!?34542$]$*%-T<FEN9RP@=&]5<'!E<D-A<V4I.PT*4$A0
    @7TU%5$A/1"A3=')I;F<L('1R:6TI.PT*#0HC96YD:68`
    `
    end

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-internals @
categoriesphp
postedNov 4, '05 at 8:04a
activeNov 16, '05 at 10:58p
posts9
users4
websitephp.net

People

Translate

site design / logo © 2022 Grokbase