aboutsummaryrefslogtreecommitdiffhomepage
path: root/php
diff options
context:
space:
mode:
authorGravatar Paul Yang <TeBoring@users.noreply.github.com>2017-02-11 16:36:17 -0800
committerGravatar GitHub <noreply@github.com>2017-02-11 16:36:17 -0800
commit74eb9a0a304a3261f3c83e100f51081986ac8ba6 (patch)
treed7171743decd0b21fdf60fc76d5fd0509ebceeda /php
parentef927cc428db7bf41d3a593a16a8f1a0fe6306c5 (diff)
Add clear method to PHP message (#2700)
Diffstat (limited to 'php')
-rw-r--r--php/ext/google/protobuf/message.c19
-rw-r--r--php/ext/google/protobuf/protobuf.h1
-rw-r--r--php/ext/google/protobuf/storage.c21
-rw-r--r--php/src/Google/Protobuf/Internal/Message.php111
-rw-r--r--php/tests/encode_decode_test.php3
-rw-r--r--php/tests/generated_class_test.php26
-rw-r--r--php/tests/php_implementation_test.php2
-rw-r--r--php/tests/test_base.php95
-rw-r--r--php/tests/test_util.php7
9 files changed, 275 insertions, 10 deletions
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index e8b8ae81..46da9024 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -38,6 +38,7 @@ static zend_class_entry* message_type;
zend_object_handlers* message_handlers;
static zend_function_entry message_methods[] = {
+ PHP_ME(Message, clear, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, encode, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, decode, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, jsonEncode, NULL, ZEND_ACC_PUBLIC)
@@ -241,6 +242,24 @@ PHP_METHOD(Message, __construct) {
}
}
+PHP_METHOD(Message, clear) {
+ MessageHeader* msg =
+ (MessageHeader*)zend_object_store_get_object(getThis() TSRMLS_CC);
+ Descriptor* desc = msg->descriptor;
+ zend_class_entry* ce = desc->klass;
+ int i;
+
+ for (i = 0; i < msg->std.ce->default_properties_count; i++) {
+ zval_ptr_dtor(&msg->std.properties_table[i]);
+ }
+ efree(msg->std.properties_table);
+
+ zend_object_std_init(&msg->std, ce TSRMLS_CC);
+ object_properties_init(&msg->std, ce);
+ layout_init(desc->layout, message_data(msg),
+ msg->std.properties_table TSRMLS_CC);
+}
+
PHP_METHOD(Message, readOneof) {
long index;
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index 678f2682..d4737fb9 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -244,6 +244,7 @@ const char* layout_get_oneof_case(MessageLayout* layout, const void* storage,
const upb_oneofdef* oneof TSRMLS_DC);
void free_layout(MessageLayout* layout);
+PHP_METHOD(Message, clear);
PHP_METHOD(Message, readOneof);
PHP_METHOD(Message, writeOneof);
PHP_METHOD(Message, whichOneof);
diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c
index ba6ac59e..5e05b935 100644
--- a/php/ext/google/protobuf/storage.c
+++ b/php/ext/google/protobuf/storage.c
@@ -248,13 +248,30 @@ void native_slot_get_default(upb_fieldtype_t type, zval** cache TSRMLS_DC) {
CASE(DOUBLE, DOUBLE)
CASE(BOOL, BOOL)
CASE(INT32, LONG)
- CASE(INT64, LONG)
CASE(UINT32, LONG)
- CASE(UINT64, LONG)
CASE(ENUM, LONG)
#undef CASE
+#if SIZEOF_LONG == 4
+#define CASE(upb_type) \
+ case UPB_TYPE_##upb_type: { \
+ SEPARATE_ZVAL_IF_NOT_REF(cache); \
+ ZVAL_STRING(*cache, "0", 1); \
+ return; \
+ }
+#else
+#define CASE(upb_type) \
+ case UPB_TYPE_##upb_type: { \
+ SEPARATE_ZVAL_IF_NOT_REF(cache); \
+ ZVAL_LONG(*cache, 0); \
+ return; \
+ }
+#endif
+CASE(UINT64)
+CASE(INT64)
+#undef CASE
+
case UPB_TYPE_STRING:
case UPB_TYPE_BYTES: {
SEPARATE_ZVAL_IF_NOT_REF(cache);
diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index 82b94ee4..9e162a22 100644
--- a/php/src/Google/Protobuf/Internal/Message.php
+++ b/php/src/Google/Protobuf/Internal/Message.php
@@ -125,7 +125,7 @@ class Message
$oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
$oneof_name = $oneof->getName();
$this->$oneof_name = new OneofField($oneof);
- } else if ($field->getLabel() === GPBLabel::OPTIONAL &&
+ } else if ($field->getLabel() === GPBLabel::OPTIONAL &&
PHP_INT_SIZE == 4) {
switch ($field->getType()) {
case GPBType::INT64:
@@ -382,6 +382,115 @@ class Message
}
/**
+ * Clear all containing fields.
+ * @return null.
+ */
+ public function clear()
+ {
+ foreach ($this->desc->getField() as $field) {
+ $setter = $field->getSetter();
+ if ($field->isMap()) {
+ $message_type = $field->getMessageType();
+ $key_field = $message_type->getFieldByNumber(1);
+ $value_field = $message_type->getFieldByNumber(2);
+ switch ($value_field->getType()) {
+ case GPBType::MESSAGE:
+ case GPBType::GROUP:
+ $map_field = new MapField(
+ $key_field->getType(),
+ $value_field->getType(),
+ $value_field->getMessageType()->getClass());
+ $this->$setter($map_field);
+ break;
+ case GPBType::ENUM:
+ $map_field = new MapField(
+ $key_field->getType(),
+ $value_field->getType(),
+ $value_field->getEnumType()->getClass());
+ $this->$setter($map_field);
+ break;
+ default:
+ $map_field = new MapField(
+ $key_field->getType(),
+ $value_field->getType());
+ $this->$setter($map_field);
+ break;
+ }
+ } else if ($field->getLabel() === GPBLabel::REPEATED) {
+ switch ($field->getType()) {
+ case GPBType::MESSAGE:
+ case GPBType::GROUP:
+ $repeated_field = new RepeatedField(
+ $field->getType(),
+ $field->getMessageType()->getClass());
+ $this->$setter($repeated_field);
+ break;
+ case GPBType::ENUM:
+ $repeated_field = new RepeatedField(
+ $field->getType(),
+ $field->getEnumType()->getClass());
+ $this->$setter($repeated_field);
+ break;
+ default:
+ $repeated_field = new RepeatedField($field->getType());
+ $this->$setter($repeated_field);
+ break;
+ }
+ } else if ($field->getOneofIndex() !== -1) {
+ $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
+ $oneof_name = $oneof->getName();
+ $this->$oneof_name = new OneofField($oneof);
+ } else if ($field->getLabel() === GPBLabel::OPTIONAL) {
+ switch ($field->getType()) {
+ case GPBType::DOUBLE :
+ case GPBType::FLOAT :
+ $this->$setter(0.0);
+ break;
+ case GPBType::INT32 :
+ case GPBType::FIXED32 :
+ case GPBType::UINT32 :
+ case GPBType::SFIXED32 :
+ case GPBType::SINT32 :
+ case GPBType::ENUM :
+ $this->$setter(0);
+ break;
+ case GPBType::BOOL :
+ $this->$setter(false);
+ break;
+ case GPBType::STRING :
+ case GPBType::BYTES :
+ $this->$setter("");
+ break;
+ case GPBType::GROUP :
+ case GPBType::MESSAGE :
+ $null = null;
+ $this->$setter($null);
+ break;
+ }
+ if (PHP_INT_SIZE == 4) {
+ switch ($field->getType()) {
+ case GPBType::INT64:
+ case GPBType::UINT64:
+ case GPBType::FIXED64:
+ case GPBType::SFIXED64:
+ case GPBType::SINT64:
+ $this->$setter("0");
+ }
+ } else {
+ switch ($field->getType()) {
+ case GPBType::INT64:
+ case GPBType::UINT64:
+ case GPBType::FIXED64:
+ case GPBType::SFIXED64:
+ case GPBType::SINT64:
+ $this->$setter(0);
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Parses a protocol buffer contained in a string.
*
* This function takes a string in the (non-human-readable) binary wire
diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php
index 7eb815ad..3218aa63 100644
--- a/php/tests/encode_decode_test.php
+++ b/php/tests/encode_decode_test.php
@@ -22,7 +22,8 @@ class EncodeDecodeTest extends TestBase
$this->expectFields($from);
$data = $from->encode();
- $this->assertSame(TestUtil::getGoldenTestMessage(), $data);
+ $this->assertSame(bin2hex(TestUtil::getGoldenTestMessage()),
+ bin2hex($data));
}
public function testDecode()
diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php
index d347e8b4..83ce1139 100644
--- a/php/tests/generated_class_test.php
+++ b/php/tests/generated_class_test.php
@@ -2,6 +2,7 @@
require_once('generated/NoNameSpaceEnum.php');
require_once('generated/NoNameSpaceMessage.php');
+require_once('test_base.php');
require_once('test_util.php');
use Google\Protobuf\Internal\RepeatedField;
@@ -10,7 +11,7 @@ use Foo\TestEnum;
use Foo\TestMessage;
use Foo\TestMessage_Sub;
-class GeneratedClassTest extends PHPUnit_Framework_TestCase
+class GeneratedClassTest extends TestBase
{
#########################################################
@@ -608,14 +609,29 @@ class GeneratedClassTest extends PHPUnit_Framework_TestCase
}
#########################################################
+ # Test clear method.
+ #########################################################
+
+ public function testMessageClear()
+ {
+ $m = new TestMessage();
+ $this->setFields($m);
+ $this->expectFields($m);
+ $m->clear();
+ $this->expectEmptyFields($m);
+ }
+
+ #########################################################
# Test message/enum without namespace.
#########################################################
- public function testMessageWithoutNamespace() {
- $m = new NoNameSpaceMessage();
+ public function testMessageWithoutNamespace()
+ {
+ $m = new NoNameSpaceMessage();
}
- public function testEnumWithoutNamespace() {
- $m = new NoNameSpaceEnum();
+ public function testEnumWithoutNamespace()
+ {
+ $m = new NoNameSpaceEnum();
}
}
diff --git a/php/tests/php_implementation_test.php b/php/tests/php_implementation_test.php
index ac7c13dc..00125db4 100644
--- a/php/tests/php_implementation_test.php
+++ b/php/tests/php_implementation_test.php
@@ -496,7 +496,7 @@ class ImplementationTest extends TestBase
{
$m = new TestMessage();
TestUtil::setTestMessage($m);
- $this->assertSame(447, $m->byteSize());
+ $this->assertSame(481, $m->byteSize());
}
public function testPackedByteSize()
diff --git a/php/tests/test_base.php b/php/tests/test_base.php
index d461f0f7..729fea3b 100644
--- a/php/tests/test_base.php
+++ b/php/tests/test_base.php
@@ -1,6 +1,7 @@
<?php
use Foo\TestMessage;
+use Foo\TestEnum;
use Foo\TestMessage_Sub;
class TestBase extends PHPUnit_Framework_TestCase
@@ -69,6 +70,32 @@ class TestBase extends PHPUnit_Framework_TestCase
$this->assertEquals('c', $m->getRepeatedString()[1]);
$this->assertEquals('d', $m->getRepeatedBytes()[1]);
$this->assertEquals(35, $m->getRepeatedMessage()[1]->GetA());
+
+ if (PHP_INT_SIZE == 4) {
+ $this->assertEquals('-63', $m->getMapInt64Int64()['-63']);
+ $this->assertEquals('63', $m->getMapUint64Uint64()['63']);
+ $this->assertEquals('-65', $m->getMapSint64Sint64()['-65']);
+ $this->assertEquals('67', $m->getMapFixed64Fixed64()['67']);
+ $this->assertEquals('-69', $m->getMapSfixed64Sfixed64()['-69']);
+ } else {
+ $this->assertEquals(-63, $m->getMapInt64Int64()[-63]);
+ $this->assertEquals(63, $m->getMapUint64Uint64()[63]);
+ $this->assertEquals(-65, $m->getMapSint64Sint64()[-65]);
+ $this->assertEquals(67, $m->getMapFixed64Fixed64()[67]);
+ $this->assertEquals(-69, $m->getMapSfixed64Sfixed64()[-69]);
+ }
+ $this->assertEquals(-62, $m->getMapInt32Int32()[-62]);
+ $this->assertEquals(62, $m->getMapUint32Uint32()[62]);
+ $this->assertEquals(-64, $m->getMapSint32Sint32()[-64]);
+ $this->assertEquals(66, $m->getMapFixed32Fixed32()[66]);
+ $this->assertEquals(-68, $m->getMapSfixed32Sfixed32()[-68]);
+ $this->assertEquals(3.5, $m->getMapInt32Float()[1]);
+ $this->assertEquals(3.6, $m->getMapInt32Double()[1]);
+ $this->assertEquals(true , $m->getMapBoolBool()[true]);
+ $this->assertEquals('e', $m->getMapStringString()['e']);
+ $this->assertEquals('f', $m->getMapInt32Bytes()[1]);
+ $this->assertEquals(TestEnum::ONE, $m->getMapInt32Enum()[1]);
+ $this->assertEquals(36, $m->getMapInt32Message()[1]->GetA());
}
public function expectEmptyFields(TestMessage $m)
@@ -83,7 +110,10 @@ class TestBase extends PHPUnit_Framework_TestCase
$this->assertSame(false, $m->getOptionalBool());
$this->assertSame('', $m->getOptionalString());
$this->assertSame('', $m->getOptionalBytes());
+ $this->assertSame(0, $m->getOptionalEnum());
$this->assertNull($m->getOptionalMessage());
+ $this->assertNull($m->getOptionalIncludedMessage());
+ $this->assertNull($m->getRecursive());
if (PHP_INT_SIZE == 4) {
$this->assertSame("0", $m->getOptionalInt64());
$this->assertSame("0", $m->getOptionalUint64());
@@ -97,6 +127,71 @@ class TestBase extends PHPUnit_Framework_TestCase
$this->assertSame(0, $m->getOptionalFixed64());
$this->assertSame(0, $m->getOptionalSfixed64());
}
+
+ $this->assertEquals(0, count($m->getRepeatedInt32()));
+ $this->assertEquals(0, count($m->getRepeatedUint32()));
+ $this->assertEquals(0, count($m->getRepeatedInt64()));
+ $this->assertEquals(0, count($m->getRepeatedUint64()));
+ $this->assertEquals(0, count($m->getRepeatedSint32()));
+ $this->assertEquals(0, count($m->getRepeatedSint64()));
+ $this->assertEquals(0, count($m->getRepeatedFixed32()));
+ $this->assertEquals(0, count($m->getRepeatedFixed64()));
+ $this->assertEquals(0, count($m->getRepeatedSfixed32()));
+ $this->assertEquals(0, count($m->getRepeatedSfixed64()));
+ $this->assertEquals(0, count($m->getRepeatedFloat()));
+ $this->assertEquals(0, count($m->getRepeatedDouble()));
+ $this->assertEquals(0, count($m->getRepeatedBool()));
+ $this->assertEquals(0, count($m->getRepeatedString()));
+ $this->assertEquals(0, count($m->getRepeatedBytes()));
+ $this->assertEquals(0, count($m->getRepeatedEnum()));
+ $this->assertEquals(0, count($m->getRepeatedMessage()));
+ $this->assertEquals(0, count($m->getRepeatedRecursive()));
+
+ $this->assertSame("", $m->getMyOneof());
+ $this->assertSame(0, $m->getOneofInt32());
+ $this->assertSame(0, $m->getOneofUint32());
+ $this->assertSame(0, $m->getOneofSint32());
+ $this->assertSame(0, $m->getOneofFixed32());
+ $this->assertSame(0, $m->getOneofSfixed32());
+ $this->assertSame(0.0, $m->getOneofFloat());
+ $this->assertSame(0.0, $m->getOneofDouble());
+ $this->assertSame(false, $m->getOneofBool());
+ $this->assertSame('', $m->getOneofString());
+ $this->assertSame('', $m->getOneofBytes());
+ $this->assertSame(0, $m->getOneofEnum());
+ $this->assertNull($m->getOptionalMessage());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame("0", $m->getOneofInt64());
+ $this->assertSame("0", $m->getOneofUint64());
+ $this->assertSame("0", $m->getOneofSint64());
+ $this->assertSame("0", $m->getOneofFixed64());
+ $this->assertSame("0", $m->getOneofSfixed64());
+ } else {
+ $this->assertSame(0, $m->getOneofInt64());
+ $this->assertSame(0, $m->getOneofUint64());
+ $this->assertSame(0, $m->getOneofSint64());
+ $this->assertSame(0, $m->getOneofFixed64());
+ $this->assertSame(0, $m->getOneofSfixed64());
+ }
+
+ $this->assertEquals(0, count($m->getMapInt64Int64()));
+ $this->assertEquals(0, count($m->getMapUint64Uint64()));
+ $this->assertEquals(0, count($m->getMapSint64Sint64()));
+ $this->assertEquals(0, count($m->getMapFixed64Fixed64()));
+ $this->assertEquals(0, count($m->getMapInt32Int32()));
+ $this->assertEquals(0, count($m->getMapUint32Uint32()));
+ $this->assertEquals(0, count($m->getMapSint32Sint32()));
+ $this->assertEquals(0, count($m->getMapFixed32Fixed32()));
+ $this->assertEquals(0, count($m->getMapSfixed32Sfixed32()));
+ $this->assertEquals(0, count($m->getMapSfixed64Sfixed64()));
+ $this->assertEquals(0, count($m->getMapInt32Float()));
+ $this->assertEquals(0, count($m->getMapInt32Double()));
+ $this->assertEquals(0, count($m->getMapBoolBool()));
+ $this->assertEquals(0, count($m->getMapStringString()));
+ $this->assertEquals(0, count($m->getMapInt32Bytes()));
+ $this->assertEquals(0, count($m->getMapInt32Enum()));
+ $this->assertEquals(0, count($m->getMapInt32Message()));
+ $this->assertEquals(0, count($m->getMapRecursive()));
}
// This test is to avoid the warning of no test by php unit.
diff --git a/php/tests/test_util.php b/php/tests/test_util.php
index 7f2aae15..b7db5c1d 100644
--- a/php/tests/test_util.php
+++ b/php/tests/test_util.php
@@ -118,6 +118,8 @@ class TestUtil
$m->getMapSint64Sint64()[-65] = -65;
$m->getMapFixed32Fixed32()[66] = 66;
$m->getMapFixed64Fixed64()[67] = 67;
+ $m->getMapSfixed32Sfixed32()[-68] = -68;
+ $m->getMapSfixed64Sfixed64()[-69] = -69;
$m->getMapInt32Float()[1] = 3.5;
$m->getMapInt32Double()[1] = 3.6;
$m->getMapBoolBool()[true] = true;
@@ -213,16 +215,19 @@ class TestUtil
assert('63' === $m->getMapUint64Uint64()['63']);
assert('-65' === $m->getMapSint64Sint64()['-65']);
assert('67' === $m->getMapFixed64Fixed64()['67']);
+ assert('-69' === $m->getMapSfixed64Sfixed64()['-69']);
} else {
assert(-63 === $m->getMapInt64Int64()[-63]);
assert(63 === $m->getMapUint64Uint64()[63]);
assert(-65 === $m->getMapSint64Sint64()[-65]);
assert(67 === $m->getMapFixed64Fixed64()[67]);
+ assert(-69 === $m->getMapSfixed64Sfixed64()[-69]);
}
assert(-62 === $m->getMapInt32Int32()[-62]);
assert(62 === $m->getMapUint32Uint32()[62]);
assert(-64 === $m->getMapSint32Sint32()[-64]);
assert(66 === $m->getMapFixed32Fixed32()[66]);
+ assert(-68 === $m->getMapSfixed32Sfixed32()[-68]);
assert(3.5 === $m->getMapInt32Float()[1]);
assert(3.6 === $m->getMapInt32Double()[1]);
assert(true === $m->getMapBoolBool()[true]);
@@ -296,6 +301,8 @@ class TestUtil
"E20406088101108101" .
"EA040A0D420000001542000000" .
"F20412094300000000000000114300000000000000" .
+ "FA040A0DBCFFFFFF15BCFFFFFF" .
+ "82051209BBFFFFFFFFFFFFFF11BBFFFFFFFFFFFFFF" .
"8A050708011500006040" .
"92050B080111CDCCCCCCCCCC0C40" .
"9A050408011001" .