|
@@ -1402,7 +1402,6 @@ static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink,
|
|
RepeatedField* intern = UNBOX(RepeatedField, array);
|
|
RepeatedField* intern = UNBOX(RepeatedField, array);
|
|
HashTable *ht = PHP_PROTO_HASH_OF(intern->array);
|
|
HashTable *ht = PHP_PROTO_HASH_OF(intern->array);
|
|
size = zend_hash_num_elements(ht);
|
|
size = zend_hash_num_elements(ht);
|
|
- // size = zend_hash_num_elements(PHP_PROTO_HASH_OF(intern->array));
|
|
|
|
if (size == 0) return;
|
|
if (size == 0) return;
|
|
|
|
|
|
upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
|
|
upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
|
|
@@ -1615,11 +1614,101 @@ PHP_METHOD(Message, mergeFromJsonString) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-PHP_METHOD(Message, discardUnknownFields) {
|
|
|
|
- MessageHeader* msg = UNBOX(MessageHeader, getThis());
|
|
|
|
|
|
+// TODO(teboring): refactoring with putrawmsg
|
|
|
|
+static void discard_unknown_fields(MessageHeader* msg) {
|
|
|
|
+ upb_msg_field_iter it;
|
|
|
|
+
|
|
stringsink* unknown = DEREF(message_data(msg), 0, stringsink*);
|
|
stringsink* unknown = DEREF(message_data(msg), 0, stringsink*);
|
|
if (unknown != NULL) {
|
|
if (unknown != NULL) {
|
|
stringsink_uninit(unknown);
|
|
stringsink_uninit(unknown);
|
|
DEREF(message_data(msg), 0, stringsink*) = NULL;
|
|
DEREF(message_data(msg), 0, stringsink*) = NULL;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // Recursively discard unknown fields of submessages.
|
|
|
|
+ Descriptor* desc = msg->descriptor;
|
|
|
|
+ TSRMLS_FETCH();
|
|
|
|
+ for (upb_msg_field_begin(&it, desc->msgdef);
|
|
|
|
+ !upb_msg_field_done(&it);
|
|
|
|
+ upb_msg_field_next(&it)) {
|
|
|
|
+ upb_fielddef* f = upb_msg_iter_field(&it);
|
|
|
|
+ uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset;
|
|
|
|
+ bool containing_oneof = false;
|
|
|
|
+
|
|
|
|
+ if (upb_fielddef_containingoneof(f)) {
|
|
|
|
+ uint32_t oneof_case_offset =
|
|
|
|
+ desc->layout->fields[upb_fielddef_index(f)].case_offset;
|
|
|
|
+ // For a oneof, check that this field is actually present -- skip all the
|
|
|
|
+ // below if not.
|
|
|
|
+ if (DEREF(message_data(msg), oneof_case_offset, uint32_t) !=
|
|
|
|
+ upb_fielddef_number(f)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ // Otherwise, fall through to the appropriate singular-field handler
|
|
|
|
+ // below.
|
|
|
|
+ containing_oneof = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (is_map_field(f)) {
|
|
|
|
+ MapIter map_it;
|
|
|
|
+ int len, size;
|
|
|
|
+ const upb_fielddef* value_field;
|
|
|
|
+
|
|
|
|
+ value_field = map_field_value(f);
|
|
|
|
+ if (!upb_fielddef_issubmsg(value_field)) continue;
|
|
|
|
+
|
|
|
|
+ zval* map_php = CACHED_PTR_TO_ZVAL_PTR(
|
|
|
|
+ DEREF(message_data(msg), offset, CACHED_VALUE*));
|
|
|
|
+ if (map_php == NULL) continue;
|
|
|
|
+
|
|
|
|
+ Map* intern = UNBOX(Map, map_php);
|
|
|
|
+ for (map_begin(map_php, &map_it TSRMLS_CC);
|
|
|
|
+ !map_done(&map_it); map_next(&map_it)) {
|
|
|
|
+ upb_value value = map_iter_value(&map_it, &len);
|
|
|
|
+ void* memory = raw_value(upb_value_memory(&value), value_field);
|
|
|
|
+#if PHP_MAJOR_VERSION < 7
|
|
|
|
+ MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory);
|
|
|
|
+#else
|
|
|
|
+ MessageHeader *submsg =
|
|
|
|
+ (MessageHeader*)((char*)(Z_OBJ_P((zval*)memory)) -
|
|
|
|
+ XtOffsetOf(MessageHeader, std));
|
|
|
|
+#endif
|
|
|
|
+ discard_unknown_fields(submsg);
|
|
|
|
+ }
|
|
|
|
+ } else if (upb_fielddef_isseq(f)) {
|
|
|
|
+ if (!upb_fielddef_issubmsg(f)) continue;
|
|
|
|
+
|
|
|
|
+ zval* array_php = CACHED_PTR_TO_ZVAL_PTR(
|
|
|
|
+ DEREF(message_data(msg), offset, CACHED_VALUE*));
|
|
|
|
+ if (array_php == NULL) continue;
|
|
|
|
+
|
|
|
|
+ int size, i;
|
|
|
|
+ RepeatedField* intern = UNBOX(RepeatedField, array_php);
|
|
|
|
+ HashTable *ht = PHP_PROTO_HASH_OF(intern->array);
|
|
|
|
+ size = zend_hash_num_elements(ht);
|
|
|
|
+ if (size == 0) continue;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < size; i++) {
|
|
|
|
+ void* memory = repeated_field_index_native(intern, i TSRMLS_CC);
|
|
|
|
+#if PHP_MAJOR_VERSION < 7
|
|
|
|
+ MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory);
|
|
|
|
+#else
|
|
|
|
+ MessageHeader *submsg =
|
|
|
|
+ (MessageHeader*)((char*)(Z_OBJ_P((zval*)memory)) -
|
|
|
|
+ XtOffsetOf(MessageHeader, std));
|
|
|
|
+#endif
|
|
|
|
+ discard_unknown_fields(submsg);
|
|
|
|
+ }
|
|
|
|
+ } else if (upb_fielddef_issubmsg(f)) {
|
|
|
|
+ zval* submsg_php = CACHED_PTR_TO_ZVAL_PTR(
|
|
|
|
+ DEREF(message_data(msg), offset, CACHED_VALUE*));
|
|
|
|
+ if (Z_TYPE_P(submsg_php) == IS_NULL) continue;
|
|
|
|
+ MessageHeader* submsg = UNBOX(MessageHeader, submsg_php);
|
|
|
|
+ discard_unknown_fields(submsg);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+PHP_METHOD(Message, discardUnknownFields) {
|
|
|
|
+ MessageHeader* msg = UNBOX(MessageHeader, getThis());
|
|
|
|
+ discard_unknown_fields(msg);
|
|
}
|
|
}
|