improve symbol comparison
authorMichael Wallner <mike@php.net>
Wed, 15 Dec 2021 19:54:58 +0000 (20:54 +0100)
committerMichael Wallner <mike@php.net>
Wed, 15 Dec 2021 19:54:58 +0000 (20:54 +0100)
ion.c
ion_private.h

diff --git a/ion.c b/ion.c
index a4da27ef2a0ff0ae306b59119099f6c98af9a7e2..5a691fd3a37a4ce68efe9e4968c7bbeaa4dd2adc 100644 (file)
--- a/ion.c
+++ b/ion.c
@@ -1532,6 +1532,7 @@ PHP_MINIT_FUNCTION(ion)
 
        // Symbol
        php_ion_register(symbol, Symbol);
+       oh_Symbol.compare = php_ion_symbol_zval_compare;
        php_ion_register(symbol_iloc, Symbol_ImportLocation);
        php_ion_register(symbol_table, Symbol_Table);
        ce_Symbol_System = register_class_ion_Symbol_System();
index a4d89d0449e2caef43f8b460d371f5977be08e1b..809f8532618933d371cdeab49e131cf9f52c280c 100644 (file)
@@ -332,6 +332,27 @@ typedef struct php_ion_symbol {
        zend_object *iloc, std;
 } php_ion_symbol;
 
+static inline int php_ion_symbol_zval_compare(zval *zv1, zval *zv2) {
+       zend_string *zs1 = zval_get_string(zv1);
+       zend_string *zs2 = zval_get_string(zv2);
+
+       if (EG(exception)) {
+               return 0;
+       }
+
+       int result;
+       if (zs1->len > zs2->len) {
+               result = 1;
+       } else if (zs2->len > zs1->len) {
+               result = -1;
+       } else {
+               result = memcmp(zs1->val, zs2->val, zs1->len);
+       }
+       zend_string_release(zs1);
+       zend_string_release(zs2);
+       return result;
+}
+
 static inline void php_ion_symbol_ctor(php_ion_symbol *obj)
 {
        zend_update_property_long(obj->std.ce, &obj->std, ZEND_STRL("sid"),
@@ -1492,6 +1513,7 @@ static void php_ion_unserialize_props(php_ion_unserializer *ser, zval *return_va
 }
 
 /**
+ * @link https://amzn.github.io/ion-docs/docs/spec.html#struct
  * When two fields in the same struct have the same name [...] Implementations must preserve all such fields,
  * i.e., they may not discard fields that have repeated names. However, implementations may reorder fields
  * (the binary format identifies structs that are sorted by symbolID), so certain operations may lead to