aboutsummaryrefslogtreecommitdiffhomepage
path: root/php/src/Google/Protobuf
diff options
context:
space:
mode:
Diffstat (limited to 'php/src/Google/Protobuf')
-rw-r--r--php/src/Google/Protobuf/Internal/GPBUtil.php9
-rw-r--r--php/src/Google/Protobuf/Internal/GPBWire.php85
-rw-r--r--php/src/Google/Protobuf/Internal/InputStream.php9
-rw-r--r--php/src/Google/Protobuf/Internal/Message.php142
-rw-r--r--php/src/Google/Protobuf/descriptor.php4
5 files changed, 212 insertions, 37 deletions
diff --git a/php/src/Google/Protobuf/Internal/GPBUtil.php b/php/src/Google/Protobuf/Internal/GPBUtil.php
index 30d7350f..ba1d2eb3 100644
--- a/php/src/Google/Protobuf/Internal/GPBUtil.php
+++ b/php/src/Google/Protobuf/Internal/GPBUtil.php
@@ -43,8 +43,15 @@ class GPBUtil
if ($isNeg) {
$value = bcsub(0, $value);
}
+
$high = (int) bcdiv(bcadd($value, 1), 4294967296);
- $low = (int) bcmod($value, 4294967296);
+ $low = bcmod($value, 4294967296);
+ if (bccomp($low, 2147483647) > 0) {
+ $low = (int) bcsub($low, 4294967296);
+ } else {
+ $low = (int) $low;
+ }
+
if ($isNeg) {
$high = ~$high;
$low = ~$low;
diff --git a/php/src/Google/Protobuf/Internal/GPBWire.php b/php/src/Google/Protobuf/Internal/GPBWire.php
index 7e2c124f..f75e0861 100644
--- a/php/src/Google/Protobuf/Internal/GPBWire.php
+++ b/php/src/Google/Protobuf/Internal/GPBWire.php
@@ -437,34 +437,65 @@ class GPBWire
public static function varint64Size($value)
{
- if ($value < 0) {
- return 10;
- }
- if ($value < (1 << 7)) {
- return 1;
- }
- if ($value < (1 << 14)) {
- return 2;
- }
- if ($value < (1 << 21)) {
- return 3;
- }
- if ($value < (1 << 28)) {
- return 4;
- }
- if ($value < (1 << 35)) {
- return 5;
- }
- if ($value < (1 << 42)) {
- return 6;
- }
- if ($value < (1 << 49)) {
- return 7;
- }
- if ($value < (1 << 56)) {
- return 8;
+ if (PHP_INT_SIZE == 4) {
+ if (bccomp($value, 0) < 0) {
+ return 10;
+ }
+ if (bccomp($value, 1 << 7) < 0) {
+ return 1;
+ }
+ if (bccomp($value, 1 << 14) < 0) {
+ return 2;
+ }
+ if (bccomp($value, 1 << 21) < 0) {
+ return 3;
+ }
+ if (bccomp($value, 1 << 28) < 0) {
+ return 4;
+ }
+ if (bccomp($value, '34359738368') < 0) {
+ return 5;
+ }
+ if (bccomp($value, '4398046511104') < 0) {
+ return 6;
+ }
+ if (bccomp($value, '562949953421312') < 0) {
+ return 7;
+ }
+ if (bccomp($value, '72057594037927936') < 0) {
+ return 8;
+ }
+ return 9;
+ } else {
+ if ($value < 0) {
+ return 10;
+ }
+ if ($value < (1 << 7)) {
+ return 1;
+ }
+ if ($value < (1 << 14)) {
+ return 2;
+ }
+ if ($value < (1 << 21)) {
+ return 3;
+ }
+ if ($value < (1 << 28)) {
+ return 4;
+ }
+ if ($value < (1 << 35)) {
+ return 5;
+ }
+ if ($value < (1 << 42)) {
+ return 6;
+ }
+ if ($value < (1 << 49)) {
+ return 7;
+ }
+ if ($value < (1 << 56)) {
+ return 8;
+ }
+ return 9;
}
- return 9;
}
public static function serializeFieldToStream(
diff --git a/php/src/Google/Protobuf/Internal/InputStream.php b/php/src/Google/Protobuf/Internal/InputStream.php
index c5a76d5d..bf052c2f 100644
--- a/php/src/Google/Protobuf/Internal/InputStream.php
+++ b/php/src/Google/Protobuf/Internal/InputStream.php
@@ -46,6 +46,9 @@ function combineInt32ToInt64($high, $low)
}
}
$result = bcadd(bcmul($high, 4294967296), $low);
+ if ($low < 0) {
+ $result = bcadd($result, 4294967296);
+ }
if ($isNeg) {
$result = bcsub(0, $result);
}
@@ -179,9 +182,9 @@ class InputStream
if ($bits >= 32) {
$high |= (($b & 0x7F) << ($bits - 32));
} else if ($bits > 25){
- $high_bits = $bits - 25;
- $low = ($low | (($b & 0x7F) << $bits)) & (int) 0xFFFFFFFF;
- $high = $b & ((0x1 << $high_bits) -1);
+ // $bits is 28 in this case.
+ $low |= (($b & 0x7F) << 28);
+ $high = ($b & 0x7F) >> 4;
} else {
$low |= (($b & 0x7F) << $bits);
}
diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index 3d1f1598..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:
@@ -163,6 +163,17 @@ class Message
$oneof_field->setNumber($number);
}
+ protected function whichOneof($oneof_name)
+ {
+ $oneof_field = $this->$oneof_name;
+ $number = $oneof_field->getNumber();
+ if ($number == 0) {
+ return "";
+ }
+ $field = $this->desc->getFieldByNumber($number);
+ return $field->getName();
+ }
+
/**
* @ignore
*/
@@ -175,17 +186,22 @@ class Message
case GPBType::FLOAT:
return 0.0;
case GPBType::UINT32:
- case GPBType::UINT64:
case GPBType::INT32:
- case GPBType::INT64:
case GPBType::FIXED32:
- case GPBType::FIXED64:
case GPBType::SFIXED32:
- case GPBType::SFIXED64:
case GPBType::SINT32:
- case GPBType::SINT64:
case GPBType::ENUM:
return 0;
+ case GPBType::INT64:
+ case GPBType::UINT64:
+ case GPBType::FIXED64:
+ case GPBType::SFIXED64:
+ case GPBType::SINT64:
+ if (PHP_INT_SIZE === 4) {
+ return '0';
+ } else {
+ return 0;
+ }
case GPBType::BOOL:
return false;
case GPBType::STRING:
@@ -366,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
@@ -395,6 +520,11 @@ class Message
$number = GPBWire::getTagFieldNumber($tag);
$field = $this->desc->getFieldByNumber($number);
+ // Check whether we retrieved a known field
+ if ($field === NULL) {
+ continue;
+ }
+
if (!$this->parseFieldFromStream($tag, $input, $field)) {
return false;
}
diff --git a/php/src/Google/Protobuf/descriptor.php b/php/src/Google/Protobuf/descriptor.php
index ef6b9dcf..9e56ef27 100644
--- a/php/src/Google/Protobuf/descriptor.php
+++ b/php/src/Google/Protobuf/descriptor.php
@@ -155,7 +155,11 @@ class Descriptor
public function getFieldByNumber($number)
{
+ if (!isset($this->field[$number])) {
+ return NULL;
+ } else {
return $this->field[$number];
+ }
}
public function setClass($klass)