|
|
|
@ -37,6 +37,7 @@ |
|
|
|
|
|
|
|
|
|
#include "arena.h" |
|
|
|
|
#include "convert.h" |
|
|
|
|
#include "message.h" |
|
|
|
|
#include "php-upb.h" |
|
|
|
|
#include "protobuf.h" |
|
|
|
|
|
|
|
|
@ -90,6 +91,28 @@ static void MapField_destructor(zend_object* obj) { |
|
|
|
|
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, |
|
|
|
|
int type, void **cache_slot) { |
|
|
|
|
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 ////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -578,6 +622,7 @@ void Map_ModuleInit() { |
|
|
|
|
h = &MapField_object_handlers; |
|
|
|
|
memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); |
|
|
|
|
h->dtor_obj = MapField_destructor; |
|
|
|
|
h->compare_objects = MapField_compare_objects; |
|
|
|
|
h->get_properties = Map_GetProperties; |
|
|
|
|
h->get_property_ptr_ptr = Map_GetPropertyPtrPtr; |
|
|
|
|
|
|
|
|
|