|
@@ -37,6 +37,7 @@
|
|
|
|
|
|
#include "arena.h"
|
|
#include "arena.h"
|
|
#include "convert.h"
|
|
#include "convert.h"
|
|
|
|
+#include "message.h"
|
|
#include "php-upb.h"
|
|
#include "php-upb.h"
|
|
#include "protobuf.h"
|
|
#include "protobuf.h"
|
|
|
|
|
|
@@ -90,6 +91,28 @@ static void MapField_destructor(zend_object* obj) {
|
|
zend_object_std_dtor(&intern->std);
|
|
zend_object_std_dtor(&intern->std);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * MapField_compare_objects()
|
|
|
|
+ *
|
|
|
|
+ * Object handler for comparing two repeated field objects. Called whenever PHP
|
|
|
|
+ * code does:
|
|
|
|
+ *
|
|
|
|
+ * $map1 == $map2
|
|
|
|
+ */
|
|
|
|
+static int MapField_compare_objects(zval *map1, zval *map2) {
|
|
|
|
+ MapField* intern1 = (MapField*)Z_OBJ_P(map1);
|
|
|
|
+ MapField* intern2 = (MapField*)Z_OBJ_P(map2);
|
|
|
|
+ const upb_msgdef *m = intern1->desc ? intern1->desc->msgdef : NULL;
|
|
|
|
+ upb_fieldtype_t key_type = intern1->key_type;
|
|
|
|
+ upb_fieldtype_t val_type = intern1->val_type;
|
|
|
|
+
|
|
|
|
+ if (key_type != intern2->key_type) return 1;
|
|
|
|
+ if (val_type != intern2->val_type) return 1;
|
|
|
|
+ if (intern1->desc != intern2->desc) return 1;
|
|
|
|
+
|
|
|
|
+ return MapEq(intern1->map, intern2->map, key_type, val_type, m) ? 0 : 1;
|
|
|
|
+}
|
|
|
|
+
|
|
static zval *Map_GetPropertyPtrPtr(PROTO_VAL *object, PROTO_STR *member,
|
|
static zval *Map_GetPropertyPtrPtr(PROTO_VAL *object, PROTO_STR *member,
|
|
int type, void **cache_slot) {
|
|
int type, void **cache_slot) {
|
|
return NULL; // We don't offer direct references to our properties.
|
|
return NULL; // We don't offer direct references to our properties.
|
|
@@ -185,6 +208,27 @@ upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+bool MapEq(const upb_map *m1, const upb_map *m2, upb_fieldtype_t key_type,
|
|
|
|
+ upb_fieldtype_t val_type, const upb_msgdef *m) {
|
|
|
|
+ size_t iter = UPB_MAP_BEGIN;
|
|
|
|
+
|
|
|
|
+ if ((m1 == NULL) != (m2 == NULL)) return false;
|
|
|
|
+ if (m1 == NULL) return true;
|
|
|
|
+ if (upb_map_size(m1) != upb_map_size(m2)) return false;
|
|
|
|
+
|
|
|
|
+ while (upb_mapiter_next(m1, &iter)) {
|
|
|
|
+ upb_msgval key = upb_mapiter_key(m1, iter);
|
|
|
|
+ upb_msgval val1 = upb_mapiter_value(m1, iter);
|
|
|
|
+ upb_msgval val2;
|
|
|
|
+
|
|
|
|
+ if (!upb_map_get(m2, key, &val2)) return false;
|
|
|
|
+ if (!ValueEq(val1, val2, val_type, m)) return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
// MapField PHP methods ////////////////////////////////////////////////////////
|
|
// MapField PHP methods ////////////////////////////////////////////////////////
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -578,6 +622,7 @@ void Map_ModuleInit() {
|
|
h = &MapField_object_handlers;
|
|
h = &MapField_object_handlers;
|
|
memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
|
|
memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
|
|
h->dtor_obj = MapField_destructor;
|
|
h->dtor_obj = MapField_destructor;
|
|
|
|
+ h->compare_objects = MapField_compare_objects;
|
|
h->get_properties = Map_GetProperties;
|
|
h->get_properties = Map_GetProperties;
|
|
h->get_property_ptr_ptr = Map_GetPropertyPtrPtr;
|
|
h->get_property_ptr_ptr = Map_GetPropertyPtrPtr;
|
|
|
|
|