aboutsummaryrefslogtreecommitdiffhomepage
path: root/php/src
diff options
context:
space:
mode:
authorGravatar Paul Yang <TeBoring@users.noreply.github.com>2017-10-09 12:39:13 -0700
committerGravatar GitHub <noreply@github.com>2017-10-09 12:39:13 -0700
commit6032746882ea48ff6d983df8cb77e2ebf399bf0c (patch)
tree700ba1d858ea0365401b639bd7ef613c90c89743 /php/src
parent77f64bb7779ec2195f9bc4dc82497d12c18fc6b7 (diff)
Reserve unknown fields in php (#3659)
* Reserve unknown fields in upb 1) For decoding, an unknownfields will be lazily created on message, which contains bytes of unknown fields. 2) For encoding, if the unknownfields is present on message, all bytes contained in it will be serialized. * Register the function to encode unknown field at decode time. * Remove upb_handlers_setaddunknown * Use upb_sink_putunknown in decoder * Remove upb_pb_encoder_encode_unknown * Do not expose encode_unknown * Implement reserve unknown field in php Implement. * Make buffer private to CodedInputStream
Diffstat (limited to 'php/src')
-rw-r--r--php/src/Google/Protobuf/Internal/CodedInputStream.php7
-rw-r--r--php/src/Google/Protobuf/Internal/CodedOutputStream.php2
-rw-r--r--php/src/Google/Protobuf/Internal/Message.php22
3 files changed, 23 insertions, 8 deletions
diff --git a/php/src/Google/Protobuf/Internal/CodedInputStream.php b/php/src/Google/Protobuf/Internal/CodedInputStream.php
index 6131d5d1..b612da5b 100644
--- a/php/src/Google/Protobuf/Internal/CodedInputStream.php
+++ b/php/src/Google/Protobuf/Internal/CodedInputStream.php
@@ -78,13 +78,18 @@ class CodedInputStream
return $this->buffer_end - $this->current;
}
- private function current()
+ public function current()
{
return $this->total_bytes_read -
($this->buffer_end - $this->current +
$this->buffer_size_after_limit);
}
+ public function substr($start, $end)
+ {
+ return substr($this->buffer, $start, $end - $start);
+ }
+
private function recomputeBufferLimits()
{
$this->buffer_end += $this->buffer_size_after_limit;
diff --git a/php/src/Google/Protobuf/Internal/CodedOutputStream.php b/php/src/Google/Protobuf/Internal/CodedOutputStream.php
index 4525d8dd..f75e9c66 100644
--- a/php/src/Google/Protobuf/Internal/CodedOutputStream.php
+++ b/php/src/Google/Protobuf/Internal/CodedOutputStream.php
@@ -101,7 +101,7 @@ class CodedOutputStream
return true;
}
- private static function writeVarintToArray($value, &$buffer, $trim = false)
+ public static function writeVarintToArray($value, &$buffer, $trim = false)
{
$current = 0;
diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index c0a3218b..b3c4e6f1 100644
--- a/php/src/Google/Protobuf/Internal/Message.php
+++ b/php/src/Google/Protobuf/Internal/Message.php
@@ -57,6 +57,7 @@ class Message
* @ignore
*/
private $desc;
+ private $unknown = "";
/**
* @ignore
@@ -226,13 +227,14 @@ class Message
/**
* @ignore
*/
- private static function skipField($input, $tag)
+ private function skipField($input, $tag)
{
$number = GPBWire::getTagFieldNumber($tag);
if ($number === 0) {
throw new GPBDecodeException("Illegal field number zero.");
}
+ $start = $input->current();
switch (GPBWire::getTagWireType($tag)) {
case GPBWireType::VARINT:
$uint64 = 0;
@@ -240,21 +242,21 @@ class Message
throw new GPBDecodeException(
"Unexpected EOF inside varint.");
}
- return;
+ break;
case GPBWireType::FIXED64:
$uint64 = 0;
if (!$input->readLittleEndian64($uint64)) {
throw new GPBDecodeException(
"Unexpected EOF inside fixed64.");
}
- return;
+ break;
case GPBWireType::FIXED32:
$uint32 = 0;
if (!$input->readLittleEndian32($uint32)) {
throw new GPBDecodeException(
"Unexpected EOF inside fixed32.");
}
- return;
+ break;
case GPBWireType::LENGTH_DELIMITED:
$length = 0;
if (!$input->readVarint32($length)) {
@@ -266,13 +268,18 @@ class Message
throw new GPBDecodeException(
"Unexpected EOF inside length delimited data.");
}
- return;
+ break;
case GPBWireType::START_GROUP:
case GPBWireType::END_GROUP:
throw new GPBDecodeException("Unexpected wire type.");
default:
throw new GPBDecodeException("Unexpected wire type.");
}
+ $end = $input->current();
+
+ $bytes = str_repeat(chr(0), CodedOutputStream::MAX_VARINT64_BYTES);
+ $size = CodedOutputStream::writeVarintToArray($tag, $bytes, true);
+ $this->unknown .= substr($bytes, 0, $size) . $input->substr($start, $end);
}
/**
@@ -423,7 +430,7 @@ class Message
}
if ($value_format === GPBWire::UNKNOWN) {
- self::skipField($input, $tag);
+ $this->skipField($input, $tag);
return;
} elseif ($value_format === GPBWire::NORMAL_FORMAT) {
self::parseFieldFromStreamNoTag($input, $field, $value);
@@ -461,6 +468,7 @@ class Message
*/
public function clear()
{
+ $this->unknown = "";
foreach ($this->desc->getField() as $field) {
$setter = $field->getSetter();
if ($field->isMap()) {
@@ -1043,6 +1051,7 @@ class Message
return false;
}
}
+ $output->writeRaw($this->unknown, strlen($this->unknown));
return true;
}
@@ -1428,6 +1437,7 @@ class Message
foreach ($fields as $field) {
$size += $this->fieldByteSize($field);
}
+ $size += strlen($this->unknown);
return $size;
}